Disclaimer/edit: this is a fairly simple question, but I'm asking it since I'm (still) often confused by evaluation order in F#, esp. with respect to newlines vs. spaces. Trial and error always gets me where I want to, but I don't think you can really understand a language if you have to resort to trial and error.
If I write:
let res x =
x * 1 = x
|> ignore
all's fine, but if I write:
let res x =
x * 1 = x && x * -1 = -x
|> ignore
then the compiler complains (it says it expects bool -> bool
, not bool -> unit
). I would have expected the newline to act as a separator here.
Adding parentheses helps, and putting it on one line shows that it is evaluated as (X && (Y |> Z))
, where X
and Y
are boolean expressions and Z
is any function.
Is this true? And is there a simpler way to find this out? Or better, when is whitespace a significant operator and when not?
To give another example:
let v = x |> fun x -> float x |> fun y -> true
Why is y
here of type float and not of type int -> float
? This may be obvious, and I sure have programmed thousands of lines that way, it even feels natural, but why?
If the only answer to give is "operator precedence and ->
comes before |>
", so be it. But I guess/hope there's some more academical or otherwise formal though behind all this (and I still find it odd that &&
has lower prio than |>
, again, I don't understand why and in that case it feels counter-intuitive).
Looking at https://learn.microsoft.com/en-us/dotnet/articles/fsharp/language-reference/symbol-and-operator-reference/#operator-precedence it seems that &&
has higher precedence than |>
so your guess is correct and you need to add parenthesis:
let res x =
(x * 1 = x && x * -1 = -x)
|> ignore
It looks like a new line doesn't act as a separator unless it has a let binding or fall in one of the rules listed here
For example if you take this expression:
let res =
5 + 1
.GetType()
You also get an error, because it applies the .
operator to 1
not to the whole expression, so the precedence rules still holds, regardless of the newline.