请考虑以下代码:
let fn () =
let b =
8. // any expression
-b
let fn2 () =
let b =
8. // any expression
- b
“fn”编译而“fn2”不编译(注意“b”前面的空格)。错误消息是:
阻止此'let'未完成。期待一个表达。
为什么?
答案 0 :(得分:9)
F#允许各种“undentation”,允许你使用较小的缩进,但仍然保持在同一个表达式中。
其中一个合法的“不作为”是针对运营商的。你可以写
foo
|> bar
|> baz
或
foo
|> bar
|> baz
甚至
foo
|> bar
|> baz
和中缀运算符在后续行上继续相同的表达式。规则是允许您“取消”“中缀运算符的长度加上一个空格”,目的是允许您对齐您正在使用的值。一个常见的情况就像一个数字表,如
let x =
42
+ 21
+ 62
其中42以下的行允许以两个较小的缩进开始,以便下一个数字在前一个数字下对齐。
所以无论如何,这个规则在这里开始,没有空格,'二进制减去'优先于'一元减',然后中缀不足规则开始。
答案 1 :(得分:2)
fn2被解析为:
let fn2 () =
let b = 8. - b
let
块未完成,需要返回值,例如
let fn2 () =
let b = 8. - b
b
我建议你在二元运算符周围使用空格,在一元运算符之后不要使用空格。
同样,x - 2
(减法)和x -2
之间存在差异(使用参数-2调用函数x)。
答案 2 :(得分:1)
这是你对8的缩进。 当我输入此代码时:
let fn () =
let b =
8.
-b
let fn2 () =
let b =
8.
- b
它正确编译。发生的事情是,在第一个例子中,fn2相当于:
let b = 8 - b
并且编译器需要其他东西才能完成let块(我总是将let块视为“让foo = bar in expr”)。所以你错过了expr部分。在fn中,你得到“让b = 8. in -b”。