如何将所需的System.Random.Next重载传递给F#函数?

时间:2019-04-05 05:33:56

标签: function f#

刚开始使用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

enter image description here

2 个答案:

答案 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))