刚开始使用F#。有人可以告诉我为什么我不能传递带有两个int
参数并向我的int
函数返回printNext
的Next重载吗?据我所知类型正在排队……但这不是编译器所说的。
open System
let r = new Random()
let printNext (nextInt : int -> int -> int) =
let i = nextInt 0 100
printf "%d" i
let t x y = x + y
// compiles fine
printNext t
// compilation error
printNext r.Next
答案 0 :(得分:6)
问题是,您的printNext
函数采用的参数类型为int -> int -> int
,但是Random.Next
方法的类型为int * int -> int
。即您希望使用带有curried参数的函数,但是提供带有元组参数的函数。
问题不是 ,编译器无法找到正确的重载方法,而是没有采用咖喱参数的重载Random.Next
方法。
这一切似乎令人困惑,并且确实需要一些时间来适应,但是当您了解它时,使用currying是一个非常不错的工具。例如,它允许partial application。在使用F#时,一个问题是诸如Random.Next
之类的方法最初是为C#设计的,因此没有咖喱参数。
更新:我忘记了@ 3615提供的实际问题解决方案。我将其添加到此处以完成操作,不要从@ 3615的答案中提取任何内容。
在这种情况下,解决方案是围绕Random.Next
方法编写包装器。如果要多次使用它,可以将其放在变量中-否则只需使用匿名函数即可。以下任何一种都可以工作
let nextRnd x y = r.Next(x, y)
printNext nextRnd
printNext (fun x y-> r.Next(x,y))
答案 1 :(得分:2)
在这种情况下,F#编译器似乎无法推断出您需要2个参数的重载,而它选择了一个参数的重载。因此,要解决此问题,您可以像下面这样包装该方法:printNext (fun x y-> r.Next(x,y))