首页 > 解决方案 > 如何将所需的 System.Random.Next 重载传递给我的 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

在此处输入图像描述

标签: functionf#

解决方案


问题是,您的printNext函数采用 type 的参数int -> int -> int,但该Random.Next方法具有 type int * int -> int。即,您期望一个函数采用curried参数,但提供一个采用元组参数的函数。

问题在于编译器找不到正确的重载方法,而是没有Random.Next采用柯里化参数的重载方法。

这一切可能看起来令人困惑,并且确实需要一些时间来适应,但是当你了解它时,currying 是一个非常好的工具。例如,它允许部分应用。谈到 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))

推荐阅读