Generics 由以下原因导致的编译错误:警告:此构造导致代码的泛型性低于类型注释所指示的泛型。

Generics 由以下原因导致的编译错误:警告:此构造导致代码的泛型性低于类型注释所指示的泛型。,generics,f#,Generics,F#,在我提问之前,先做一点解释。我有一个序列,我想在这个序列上执行一些折叠操作。但是评估序列速度慢且成本高(它在数据库中进行迭代),而且(尽管这里没有明确说明),我希望向用户提供渐进式输出。所以我真的很想一次完成所有的折叠。比如: theSeq |> Seq.CoFold [ line (folder1, initAcc1, action1) line (folder2, initAcc2, action2) ] 动作是在折叠完成后使用收集器完成的动作。我会这样使用它: th

在我提问之前,先做一点解释。我有一个序列,我想在这个序列上执行一些折叠操作。但是评估序列速度慢且成本高(它在数据库中进行迭代),而且(尽管这里没有明确说明),我希望向用户提供渐进式输出。所以我真的很想一次完成所有的折叠。比如:

theSeq |> Seq.CoFold [
    line (folder1, initAcc1, action1)
    line (folder2, initAcc2, action2)
]
动作
是在折叠完成后使用收集器完成的动作。我会这样使用它:

theSeq |> Seq.CoFold [
    line ((fun acc r -> acc+1), 0, (fun d -> printfn "%A" d)) // counter
    line ((fun acc r -> acc.Add(r), Set.empty, whatever) // uniques
]
我已经计算出,无论
是什么,它都应该根据seq的类型进行泛化,但它不应该取决于
initAcc的类型,或者文件夹函数本身的类型。因此,我得出了以下结论(这是行不通的):

问题是,它希望基于
'T
'State
来泛型
,这意味着我上面显示的两行互不兼容,即使它们都没有公开
acc
的类型

我尝试过其他几种方法(例如,将line转换成一个有区别的并集,将line转换成一个抽象基类,等等),在每种情况下,我都会遇到原始问题的一些其他表现形式。我真不知道下一步该去哪里

这感觉不应该是一个困难的问题,但我想我在某个地方有一个盲点。感激地接受任何暗示


谢谢

注意,
CoFold
实际上并不关心
本身,它只关心
incr
cb
,而这些仅在
't
状态下是通用的,而不是
'State
。所以不要给它
本身,只给它
incr
cb

type 'T line = ('T -> unit) * (unit -> unit)

let makeLine incr a cb: line<_> =
  let s = ref a
  let incr' t = s := incr !s t
  let cb' () = cb !s
  incr', cb'

let CoFold (folders: 'T line list) (jj: 'T seq) =
  for j in jj do
      folders |> List.iter (fun (incr,_) -> incr j)
  folders |> List.iter (fun (_,cb) -> cb() )

aSeq |> Seq.CoFold [
  makeLine f1 s1 a1
  makeLine f2 s2 a2 ]
type'T line=('T->unit)*(unit->unit)
让makeLine增加一个cb:line=
设s=ref a
让incr't=s:=incr!s t
让cb’()=cb!s
增量',cb'
let CoFold(文件夹:'T行列表)(jj:'T seq)=
对于jjdo中的j
文件夹|>List.iter(乐趣(增加)->incr j)
文件夹|>List.iter(fun(|,cb)->cb())
aSeq |>序列CoFold[
生成线f1 s1 a1
makeLine f2 s2 a2]
如果你想变得富有哲理,问题的根源在于完成
incr
cb
,将它们捆绑在一起,而它们显然不是必须的。总的来说,这是一条很好的经验法则:尽量使事物保持小而独立。

如果仔细观察,您会发现“类”(或“对象”)正是这样的:一种用多个函数完成多个数据的方法。尽量避免使用类。

回答太棒了!非常感谢你。你完全解决了我的问题。但是——更重要的是——尽管我已经知道了解决这个问题所需要的一切,但我自己永远也不可能做到这一点。是的,我确实有一个盲点。我可以看到这将如何简化我遇到的一系列其他问题。再次感谢。
type 'T line = ('T -> unit) * (unit -> unit)

let makeLine incr a cb: line<_> =
  let s = ref a
  let incr' t = s := incr !s t
  let cb' () = cb !s
  incr', cb'

let CoFold (folders: 'T line list) (jj: 'T seq) =
  for j in jj do
      folders |> List.iter (fun (incr,_) -> incr j)
  folders |> List.iter (fun (_,cb) -> cb() )

aSeq |> Seq.CoFold [
  makeLine f1 s1 a1
  makeLine f2 s2 a2 ]