何时在方法声明中使用括号?

时间:2017-10-12 07:49:50

标签: f#

如果我声明一个没有参数的方法,然后调用它(在F#-interactive中),那么我得到了预期的行为:屏幕上显示“test”。

let somefn() = 
    printfn "test"
> 
val somefn : unit -> unit

> somefn();;
test
val it : unit = ()

但是,如果我声明没有括号的方法,那么我会得到一些不同的行为:

let somefn = 
    printfn "test"
> 
test
val somefn : unit = ()

> somefn;;
val it : unit = ()

> somefn();;

  somefn();;
  ^^^^^^

C:\...\Local\Temp\stdin(4,1): error FS0003: This value is not a function and cannot be applied.

所以我不明白:

  1. 为什么没有参数的方法声明与参数不同?
  2. 当我没有括号声明时,我收到了消息: val somefn:unit =()。什么是单位=()?我现在刚刚宣布了什么?什么类型的实体现在 somefn
  3. 很明显,现在有一个名为 somefn 的实体,它指向一些可执行代码。我该如何执行该代码?我可以声明 somefn 作为结构或其他东西的成员并从那里执行吗?

1 个答案:

答案 0 :(得分:7)

上面的评论回答了这个问题,但我会补充一些细节。

定义函数时,每个参数实际上只与一个案例匹配。例如,你可以写:

let somefn 0 = 1

此功能的类型为int -> int。第一个参数被推断为int,但这会生成警告,因为还有其他未匹配的整数。 somefn 0会返回1,但somefn 1会抛出异常"The match cases were incomplete"

类型unit只有一个值:()。它实际上是输入或函数输出的“无”值。它的模式匹配看起来与值完全相同(就像空列表的[]一样),这就是为什么你可以使用()向任何函数添加单位参数的原因。这些功能完全相同:

let somefn () = ()
let somefn (x:unit) = ()
let somefn (_:unit) = ()

当你编写一个不带任何参数的函数时,你只需添加一个unit参数,这样它就是一个函数,而不是一个值,因此你会延迟它的执行。只是为了让点回家,你甚至可以添加多个unit参数,尽管你永远不需要这样做:

let somefn () () = ()
// unit -> unit -> unit