强制让我们绑定到函数而不是值

时间:2016-08-11 20:40:39

标签: f#

我有这段代码应该生成随机名称:

let generateName =
    let rnd = System.Random()
    let c1 = rnd.Next(65, 90) |> System.Convert.ToChar |> string
    let c2 = rnd.Next(65, 90) |> System.Convert.ToChar |> string
    let n = rnd.Next(0, 999)  |> string
    c1 + c2 + n

这会计算为一个字符串,这不是我想要的。添加unit-Parameter可以解决问题,但现在我必须像C#函数一样调用我的函数:

let myFunc() =
    "Hello"

myFunc()

这是我必须这样做的,还是有更惯用的方式?

3 个答案:

答案 0 :(得分:6)

此上下文中的

TL; DR: ()与C#中的含义完全不同,因此请不要像在C#中那样对其进行格式化 - 使用{{1}而let myFunc () =代替了,它更好地反映了实际的语义,并反过来阐明了你如何思考和理解代码。

在C#中,myFunc ()表示一组空参数(用于函数/构造函数定义)或参数(用于函数/构造函数调用站点);即,它定义或调用 nullary 函数。在F#中,()()类型的文字,类似于unit42类型的文字;即,它本身就是一个值,就像int是空列表的值一样。这种差异有很多不足之处。

在F#中,当您定义 [] - 仅包含let参数的函数时,就像在()中一样,您实际上正在使用模式匹配语法定义一个一元函数,其参数类型为let myFunc() =一个nullary函数!)。这种特殊的模式匹配实例被认为是理所当然的,许多人一开始并没有意识到它的模式匹配;但实际上,将函数定义为unit而不是let myFunc () =类似于let myFunc (_:unit) =而不是let myFunc [] =(并随后断言let myFunc (x:'a list) =为空)。

在F#中,当您使用x调用 let - 函数时,如()中所示,您并未表示没有参数& #39 ;;事实上,你提供了myFunc ()类型的参数,其常常使用的奇异值使其具有自己的文字语法:unit

要说服自己()与&#39;没有参数/参数&#39;不同,实际上只是另一个参数/参数,请考虑以下事实是完全合法的:< / p>

unit

正如你所看到的,给予let myFunc() (i:int) (_:unit*unit) = i let n = myFunc() 42((),()) printfn "%d" n 特殊的空白处理是愚蠢的,因为它不是特殊的。 ; - ]

总之,由于通常(必要?)将任何命名的参数/参数与空格分开,然后惯用保持一致并对< em>符号模式/值:

unit

答案 1 :(得分:5)

这正是它的工作原理。没有“有用”参数的函数需要有unit参数来实际使其成为函数。

将函数名称()与空格分开以使其看起来更少的方法y和更多的函数y并不罕见,但这纯粹是装饰性的。

答案 2 :(得分:5)

不,这就是F#的工作方式。 F#中的每个函数都必须有一个参数(带有多个参数的函数被分成多个函数,一个参数返回一个中间函数),每个函数都必须返回一些东西,即使它是单位。