Dav*_*ook 2 f# functional-programming compiler-errors
我在F#中有以下函数,不幸的是在我的折叠开头的Seq.filter中,w2Text(在比较中)没有标识Word类型.我不确定如何在这种情况下帮助编译器.编译器似乎对其他一切都很好.这是我第一次遇到这个问题.
let CreateWordRelationDB () =
let db = new AnnotatorModel()
printfn "%s" "Entered Function and created db v7"
let tweets = db.Tweets
|> Seq.cast<Tweet>
|> Seq.map(fun t -> t.Text)
let words = db.Words |> Seq.cast<Word>
words
|> Seq.fold(fun acc w1 ->
let filtacc = acc
|> Seq.filter(fun w2 ->
if(w1.Text = w2.Text) then false else true)
filtacc
|> Seq.map(fun w2 -> CreateWordRelation w1 w2 tweets)
|> Seq.iter(fun r -> db.WordRelations.Add(r) |> ignore)
db.SaveChanges() |> ignore
filtacc
) words
Run Code Online (Sandbox Code Playgroud)
有一种 - 可以说 - 比使用类型注释更优雅的方式.
这里的问题是非F#类型(Word实质上是)的类型推断不如F#record/DU类型强大.如果在使用它之前的代码中出现相应的值,编译器只能推断那些类型(因此它不是那么多的推理而是更多的"类型跟踪").
您正在fold以这种方式使用:source |> Seq.fold folder state
因此state,仍然需要确定类型,在folder函数之后,使用它.但是,您可以在此之前通过使用不太知名的||>运算符来移动它.
此运算符被定义为let inline (||>) (a, b) f = f a b并允许您在函数上"插入"两个单独的参数:(state, source) ||> Seq.fold folder
这样,state在需要知道其类型之前发生folder,并且编译器可以"记住"该类型并在相关位置使用它.
有了它,你的函数调用看起来像
(words, words) // The first is the state, the second the source
||> Seq.fold (fun acc w1 -> ... // long folder function)
Run Code Online (Sandbox Code Playgroud)
没有进一步的参数后的folder功能咖喱到Seq.fold.
(所有这些都归功于我从中学到的Ross McKinlay.)
| 归档时间: |
|
| 查看次数: |
69 次 |
| 最近记录: |