4

我正在查看以下 F# 行

for i = 0 to i=10 do
   Console.WriteLine("Hello")

我想知道上面的行不是一个语句而不是一个表达式吗?

F# 中的所有内容不应该都是表达式吗?

4

3 回答 3

8

如前所述,F# 中的每个语法结构都是一个表达式。F# 不区分语句和表达式(因此我想说 Robert 发布的 WikiPedia 引用有点误导 - F# 没有语句)。

实际上,上述情况并不完全正确,因为 F# 计算表达式中的某些构造,例如let!not expressions,但我们可以忽略它。

这意味着什么?在 C# 中,for方法调用的语法定义如下:

statement  := foreach(var v in <expression>) <statement>
            | { <statement> ... <statement> }
            | <expression>;
            | (...)

expression := <expression>.<ident>(<expression>, ..., <expression>)
            | <literal>
            | <expression> + <expression>
            | (...)

这是非常简化的,但它应该给你的想法 - 语句是不评估值的东西。它可以是foreach循环(其他循环)、语句块(具有多个语句)或带有分号的表达式(其中表达式的结果void被忽略或被忽略)。例如,表达式是方法调用、原始文字(字符串、整数)或二元运算符。

这意味着您不能在 C# 中编写某些内容 - 例如,方法调用的参数不能是语句(因为语句不会评估为值!)

另一方面,在 F# 中,一切都是表达式。这意味着只有一个语法类别:

expression := for v in <expression> do <expression>
            | <expression>; <expression>
            | <expression>.<ident>(<expression>, ..., <expression>)
            | <literal>
            | <expression> + <expression>
            | (...)

这意味着在 F# 中,所有语法结构都是表达式,包括for循环和其他循环。of 的主体for也是一个表达式,但如果表达式评估为某个值(即42),则没有意义,因此类型要求主体的结果是unit(不携带任何信息)。同样,排序 ( <expr>; <expr>) 中的第一个表达式应该返回unit- 排序的结果是第二个表达式的结果。

这使得语言更简单、更统一,但你可以写一些奇怪的东西:

let x = (for i in 0 .. 10 do printfn "%d" i); 42

这将打印从0to的数字10,然后将值定义x42。赋值是表达式 ( <expr>; <expr>) 的序列,其中第一个是for循环(它有一个类型unit,因为它不计算任何东西),第二个是42,它的计算结果是 42。

于 2012-07-02T09:54:36.813 回答
4

F# 中的每个语句,包括 if 语句和循环,都是具有明确返回类型的可组合表达式。不返回任何值的函数和表达式的返回类型为 unit。

http://en.wikipedia.org/wiki/F_Sharp_(programming_language)

于 2012-07-02T05:43:45.143 回答
0

在像 F# 这样的语言中,语句只是返回 type 值()的表达式unit。由于该unit类型只有一个值,它不传达任何信息,因此返回类型 unit 的值表示“如果我正在做任何事情,那么它是通过副作用的方式”,例如打印到控制台或写入磁盘。

Note that not everything is an expression in F#. Type definitions are not expressions. Patterns are not expressions. And so on...

于 2012-12-28T13:46:47.610 回答