开发者

Indentation bug in f#?

开发者 https://www.devze.com 2023-02-23 23:27 出处:网络
Consider the following code: let fn () = let b = 8. // any expression -b let fn2 () = let b = 8. // any expression

Consider the following code:

let fn () =
  let b =
    8. // any expression
  -b

let fn2 () =
  let b =
    8. // any expression
  - b

"fn" compiles whereas "fn2" does not (notice the space in front of "b"). The error message is:

Block followin开发者_如何转开发g this 'let' is unfinished. Expect an expression.

Why is that?


F# allows for various kinds of "undentation", where you are allowed to use a lesser indent, but still stay within the same expression.

One such legal "undent" is for operators. You can write

    foo
        |> bar
        |> baz

or

    foo
    |> bar
    |> baz

or even

    foo
 |> bar
 |> baz

and the infix operators continue the same expression on a subsequent line. The rule is that you are allowed to "undent" the "length of the infix operator plus one space", the intent being that this allows you to align the values you're using. A common case is like a table of numbers, like

let x = 
    42
  + 21
  + 62

where the line below 42 is allowed to start at a two-space lesser indent so that the next number is aligned under the prior one.

So anyway, that rule is kicking in here, and without a space, the 'binary minus' takes precedence over the 'unary minus' and then the infix undent rule kicks in.


fn2 is parsed as:

let fn2 () =
  let b = 8. - b

The let block is unfinished, it needs a return value, eg.

let fn2 () =
  let b = 8. - b
  b

I suggest you to use spaces around binary operators, and no spaces after unary operators. In the same way, there's a difference between x - 2 (substraction) and x -2 (call function x with argument -2).


It's your indenting of the 8. When I enter this code:

let fn () =
    let b =
        8.
    -b

let fn2 () = 
    let b =
        8.
    - b

It compiles correctly. What's happening is that in the first example fn2 is equivalent to:

let b = 8 - b

and the compiler needs something else to finish the let block (I always read let block as "let foo = bar in expr"). So you're missing the expr part. In the fn, you're getting "let b = 8. in -b".

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号