我刚开始学习F#。本书使用以下符号:
let name() = 3
name()
与此不同的是:
let name = 3
name
答案 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,648
到2,147,483,647
。另一个示例类型bool
只有两个值,true
和false
。
回过头来问你()
的用法是什么。如果未指定函数的输入值,则无法执行。因此,您必须为函数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"
这将按顺序打印以下内容