F# - 创建委托

Opf*_*ash 4 f# c#-to-f# unit-type

目前正在阅读一系列关于F#的博客文章,针对C#程序员.现在我已经读完了第3部分(http://www.jelovic.com/weblog/?p=220),我感到很困惑.

和...之间的不同

让readLine = Console.ReadLine()

let readLine()= Console.ReadLine()

很清楚,但为什么需要指定两个括号 - () - 在以下行:

let print(text:string)()= Console.WriteLine文本

编译器是否应该能够通过省略大括号来确定您是否声明了委托打印,因此它看起来如下所示:

let print(text:string)= Console.WriteLine文本

此外,以下几行对我来说没什么意义

通常当你有一个带有不同类型参数的函数时,编译器可以区分函数调用和委托引用,但是对于单元,你必须强制它.

这是否意味着当参数不同时,编译器可以安全地假设它是一个函数调用?

谢谢大家的答案,现在我很清楚.至于报价,我们会让它休息.

Tom*_*cek 5

介绍.我认为首先讨论简单示例中的差异是有用的,因为它有助于理解"单位"值是什么.第一个声明创建一个字符串值(并立即调用ReadLine以获取用户的输入):

> let readLine = Console.ReadLine ();;
val readLine : string
Run Code Online (Sandbox Code Playgroud)

第二个声明创建一个以单位值作为参数的函数.该函数不需要接受任何输入,但我们希望将其定义为函数,以便可以重复执行(我们需要它,因为该函数具有副作用 - 它从用户读取输入).

"unit"参数只是一种创建以某种形式作为参数的函数的方法."单元"只有一个写入的值(),因此它不代表任何信息 - 只是存在一些参数的事实:

> let readLine () = Console.ReadLine ();;
val readLine : unit -> string
Run Code Online (Sandbox Code Playgroud)

你的问题.用额外的大括号来看你的例子.这将创建一个函数,该函数将字符串作为第一个参数,并将其他"unit"值作为第二个参数.您可以从类型签名中看到:

> let print (text : string) () = Console.WriteLine text 
val print : string -> unit -> unit
Run Code Online (Sandbox Code Playgroud)

这是有效的F#声明,但它不是很有用.这意味着只有当你给它打印一些字符串以及附加的"单位"值时才会调用该函数.你可以这样称呼它:

print "Hello" ()
Run Code Online (Sandbox Code Playgroud)

即使没有附加的"unit"参数,它也是一个函数(而不是一个值),所以添加附加参数没有帮助(你总是创建一个可以调用来打印不同字符串的函数).

仍然存在这种声明可能有趣的情况.例如,您可以使用字符串作为参数调用该函数.在这种情况下,您将获得一个函数作为结果.返回的函数将取单元并将打印字符串:

let f = print "Hello" // doesn't print anything
f ()                  // prints "Hello"
f ()                  // prints "Hello" again!
Run Code Online (Sandbox Code Playgroud)

因此,编译器允许您将"单位"值用作语言中的任何其他值.这包括一开始可能看起来有点不熟悉(并且不是非常有用)的用途,但在某些情况下可以很好地理解.