F#计算表达式-类型错误



我正在与几行可怜的代码作斗争,但我无法理解这个问题——无论出于什么原因,我都无法理解F#类型系统的这一方面的原理,到目前为止,我所有的阅读都没有奏效。

有人能向我指出我在这里犯的相当愚蠢的学生错误吗?我知道我在做一个,我就是看不见!我正试图从这片痛苦的初学者土地上爬出来,所以我的目标是探索为什么这不起作用的全部原理——任何帮助都将不胜感激!

这是一个简单的练习——实际上只是一个练习,并不需要monad来执行,但我真的希望这些东西能在我的下一个项目中发挥作用。

let stringToInt str = Int32.TryParse(str)
type wk() =
member this.Bind(f , str) = f str
member this.Return(f ) = f 
let strInt = new wk()
let test a   =  strInt{let! b  = strInt.Bind a stringToInt 
return b}

let x = test  "10"  
printfn "%s" x

我得到以下信息:

Program.fs(117,14): error FS0001: This expression was expected to have type
(string -> bool * int) -> ('a -> 'a) -> 'b    
but here has type  string 

更新:基于下面的帮助,我现在有这个工作:

open System
open System.Threading
let stringToInt str = snd <| Int32.TryParse(str)   

type wk() =
member this.Bind(funct, str) =  funct str  
member this.Return(str) = str
let strInt = new wk()
//Jack P syntax!
let test2 str funct = strInt{
let! b = funct str
return b
}
let go2 = test2 ("10", stringToInt) |>  printfn "%A"

尽管工作在概念上可能还不存在——但要把价值打印出来还没有发生。我会继续努力——我已经读了很多书,这就是我得到这个练习的地方,但我想,我得到这个概念的唯一方法就是继续与它斗争。

我在博客上以一种更简单的形式取得了成功:http://richardgriffiths.azurewebsites.net/?p=2332所以我只需要打破我在类型系统中遇到的语法/概念障碍。

F#中计算表达式的全部意义在于,您不必在构建器实例上显式调用BindReturn等方法(本例中为strInt)。这就是letlet!之间的区别——在计算表达式中,let!绑定被编译,因此它们调用构建器实例的Bind方法。所以你应该这样写你的代码:

let test a =
strInt {
let! b  = stringToInt a
return b
}

然而,上面的代码仍然不能工作,因为BindReturn方法没有正确定义(它们不是一元的)。我赞同Patryk的建议(在他的评论中)——在你开始写自己的单子之前,你应该花一些时间练习简单、常见的单子(例如option)。使用F#计算表达式很容易,但定义自己的计算表达式是一个中级/高级主题。

您已经定义了Bind来接受元组参数(这对于计算生成器来说是正确的),但您正在以当前形式传递参数(strInt.Bind a stringToInt而不是strInt.Bind(a, stringToInt))。

相关内容

  • 没有找到相关文章

最新更新