9

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

let name() = 3
name()

与此有什么不同:

let name = 3
name

?

4

4 回答 4

13

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

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

为了简单起见,我们将使用:
如果没有参数,则 let 语句是value
如果有参数,那么 let 语句就是一个函数

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

所以这个

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# 具有不需要参数的函数的单位类型(),并且单位类型的唯一值是.

所以这是一个有一个x类型参数的函数int

let c x = x + 1;;

这是一个具有一个()类型参数的函数unit

let b () = System.DateTime.Now;;
于 2013-07-26T02:41:06.343 回答
11

绝对不要将其()视为函数调用或类似的语法。它只是一个值,例如 3、5、'q'、false 或 "blah"。它恰好是 type 的值,Unit实际上它是 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都是,一个接受参数并返回 3 的函数的定义Unit,就像上面的 C# 版本一样。

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

于 2013-07-26T01:57:59.893 回答
8

let name() = 3
name()

name是一个函数,类型为unit -> int

let name = 3
name

name是一个整数,类型为int

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

所以回到你的问题是什么是(). 如果你不指定函数的输入值,它就不能被执行。所以你必须为你的函数指定一个输入值来let name()=3让它执行,并且由于它的输入类型是unit,你可以使用的唯一值是()

这是定义名称函数的另一种方法:

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

并将其与以下内容进行比较:

let name : int = 3
于 2013-07-26T01:20:02.540 回答
4

Using()创建一个函数,它接受一个 type 的参数unit,而不是第二种情况,它只是一个简单的整数。

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

主要的区别是当你有

let name() = 
    printfn "hello"
    1

对比

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. 函数计算完成
于 2013-07-26T00:24:56.050 回答