Abe*_*bel 3 f# boolean operator-precedence
免责声明/编辑:这是一个相当简单的问题,但我问它,因为我(仍然)常常被F#中的评估顺序混淆,特别是.关于换行与空格.试验和错误总能让我到达我想要的地方,但如果您不得不求助于试错,我认为您不能真正理解某种语言.
如果我写:
let res x =
x * 1 = x
|> ignore
Run Code Online (Sandbox Code Playgroud)
一切都很好,但如果我写:
let res x =
x * 1 = x && x * -1 = -x
|> ignore
Run Code Online (Sandbox Code Playgroud)
然后编译器抱怨(它表示它预期bool -> bool,而不是bool -> unit).我原以为新线在这里充当分隔符.
添加括号有帮助,并将它放在一行显示它被评估为(X && (Y |> Z)),where X和Y是布尔表达式,Z是任何函数.
这是真的?有没有更简单的方法来找到它?或者更好的是,什么时候空白是一个重要的运算符,什么时候不是?
举另一个例子:
let v = x |> fun x -> float x |> fun y -> true
Run Code Online (Sandbox Code Playgroud)
为什么y这里的类型为float而不是类型int -> float?这可能是显而易见的,我确实已经编程了数千条线路,它甚至感觉很自然,但为什么呢?
如果给出的唯一答案是"运算符优先级并且->在之前|>",那么就这样吧.但我想/希望有更多的学术或其他形式,但背后的所有这些(我仍然觉得奇怪,&&prio低于|>,再次,我不明白为什么,在这种情况下,它感觉反直觉).
看看https://docs.microsoft.com/en-us/dotnet/articles/fsharp/language-reference/symbol-and-operator-reference/#operator-precedence它似乎&&具有更高的优先级,|>因此你的猜测是正确的你需要添加括号:
let res x =
(x * 1 = x && x * -1 = -x)
|> ignore
Run Code Online (Sandbox Code Playgroud)
看起来新行不作为分隔符,除非它具有let绑定或属于此处列出的规则之一
例如,如果你采用这个表达式:
let res =
5 + 1
.GetType()
Run Code Online (Sandbox Code Playgroud)
您还会收到错误,因为它将.操作符应用于1整个表达式,因此无论换行符如何,优先级规则仍然保留.