这个'()'符号是什么意思?

时间:2013-07-26 00:22:50

标签: function f# value-type unit-type

我刚开始学习F#。本书使用以下符号:

let name() = 3
name()

与此不同的是:

let name = 3
name

4 个答案:

答案 0 :(得分:13)

在回答()之前,我们先定义一些基础知识并完成一些示例。

在F#中,let statement有一个名称,零个或多个参数以及一个表达式。

为了保持这一点,我们将采用:
如果没有参数,则let语句为value 如果有参数,那么let语句是function

对于值,表达式的结果仅计算一次并绑定到标识符;这是不可改变的 对于函数,每次调用函数时都会计算表达式。

所以

let a = System.DateTime.Now;;

总是有时间首次评估或稍后调用,即

a;;
val it : System.DateTime = 1/10/2017 8:16:16 AM ...  
a;;
val it : System.DateTime = 1/10/2017 8:16:16 AM ...  
a;;
val it : System.DateTime = 1/10/2017 8:16:16 AM ...  

以及功能

let b () = System.DateTime.Now;;

每次评估时都会有一个新的时间,即

b ();;
val it : System.DateTime = 1/10/2017 8:18:41 AM ...  
b ();;
val it : System.DateTime = 1/10/2017 8:18:49 AM ...  
b ();;
val it : System.DateTime = 1/10/2017 8:20:32 AM ... 

现在解释()的含义。请注意System.DateTime.Now不需要参数。

  

当表达式不需要参数时,我们如何创建函数?

每个参数都必须有一个类型,因此对于不需要参数的函数,F#有unit type,单元类型的唯一值是()

所以这是一个函数,其中一个参数x的类型为int

let c x = x + 1;;

这是一个函数,其中一个参数()的类型为unit

let b () = System.DateTime.Now;;

答案 1 :(得分:11)

绝对不要将()视为函数调用的某种语法或类似的东西。它只是一个值,如3,5,'q',false或“blah”。它恰好是Unit类型的值,实际上它是类型单位的唯一值,但实际上它不是重点。 ()这里只是一个值。我不能强调这一点。

首先考虑

let name x = 3

这是什么?这只是在x上定义了一个函数,其中x可以是任何类型。在C#中将是:

int Name<T>(T x) 
{
    return 3;
}

现在,如果我们看一下let name () = 3(我有点建议在那里添加额外的空间,那么它使()看起来比某些句法结构更值)然后在C#中你可以认为它是类似(伪代码)

int Name<T>(T x) where T == Unit  //since "()" is the only possible value of Unit
{
    return 3;
}

或者更简单地说

int Name(Unit x)
{
    return 3;
}

所以我们看到所有let name () = 3都是一个带有Unit参数的函数的定义,并返回3,就像上面的C#版本一样。

但是,如果我们查看let name = 3那么这只是一个变量定义,就像C#中的var name = 3一样。

答案 2 :(得分:8)

let name() = 3
name()

name是一个unit -> int类型的函数。

let name = 3
name

name是一个类型为int的整数。

在F#中,每个函数都有一个输入类型和一个输出类型。 let name() = 3的输入类型为unit,其中只有一个值()。其输出类型为int,其值为–2,147,483,6482,147,483,647。另一个示例类型bool只有两个值,truefalse

回过头来问你()的用法是什么。如果未指定函数的输入值,则无法执行。因此,您必须为函数let name()=3指定一个输入值才能执行它,并且由于其输入类型为unit,因此您可以使用的唯一值是()

以下是定义名称功能的另一种方法:

let name : (unit -> int)  = (fun _ -> 3);;

并将其与:

进行比较
let name : int = 3

答案 3 :(得分:4)

使用()创建一个函数,该函数采用类型unit的参数,而不是第二种情况,它只是一个简单的整数。

当您想要控制函数的执行时,这一点尤为重要。

主要区别在于你有

let name() = 
    printfn "hello"
    1

VS

let name = 
    printfn "hello"
    1

然后

let t = name + name

将打印“你好”一次。但

let t = (name()) + (name())

将两次打印“你好”。

在考虑评估函数的顺序时,您必须小心这一点。

考虑以下计划:

let intversion = 
    printfn "creating integer constant"
    1

printfn "integer created"

let funcversion() =
    printfn "executing function"
    1

printfn "function created"

let a = intversion + intversion
printfn "integer calculation done"
let b = (funcversion()) + (funcveriosn())
printfn "function calculation done"

这将按顺序打印以下内容

  1. 创建整数常量
  2. 已创建整数
  3. 创建了功能
  4. 完成整数计算
  5. 执行功能
  6. 执行功能
  7. 功能计算已完成