Pregunta

This program:

type A = { a : int }
type B = { b : A }

//34567890
let r = {
  b = {      // line 6
    a = 2    // line 7 
  } 
}

Produces under mono/fsharpc this warning twice:

/Users/debois/git/dcr/foo.fs(7,5): warning FS0058: Possible incorrect indentation: this token is offside of context started at position (6:7). Try indenting this token further or using standard formatting conventions.

  1. Why does this warning occur at all? The f#-spec p. 228 makes me think the token 'a' following '{' sets a new offside line, in which case there should be no problem?

  2. Why does it occur twice?

Thanks,

Søren

Full output:

dcr > fsharpc foo.fs
F# Compiler for F# 3.0 (Open Source Edition)
Freely distributed under the Apache 2.0 Open Source License

/Users/debois/git/dcr/foo.fs(7,5): warning FS0058: Possible incorrect indentation: this token is offside of context started at position (6:7). Try indenting this token further or using standard formatting conventions.

/Users/debois/git/dcr/foo.fs(7,5): warning FS0058: Possible incorrect indentation: this token is offside of context started at position (6:7). Try indenting this token further or using standard formatting conventions.
dcr > 
¿Fue útil?

Solución 2

I finally worked it out. From the F# spec pp. 229–230, here are the pertinent rule about when offside contexts (lines) are introduced (rule numbering is mine):

(i) The column of the first token of a (, { or begin token.

(ii) Immediately after an = token is encountered in a record expression when the subsequent token either (a) occurs on the next line or (b) is one of try, match, if, let, for, while or use.

Now recall the problem:

//34567890
let r = {
  b = {      // line 6
    a = 2    // line 7 
  } 
}

The b on line 6 follows a { and so pushes an offside-line on column 3 by (i). Then, the { on line 6 follows a record expression = and so pushes a new offside line on column 7 by (ii). The a on line 7 column 5 violates that offside line.

The tricky bit is that the { on line 5 makes the next token define an offside-line, whereas the { on line 6 is itself an offside line (because it follows a record-expression equal sign).

Otros consejos

reformat your code as

type A = { a : int }
type B = { b : A }

//34567890
let r = { b = { a = 2 } }

or

let r =
    {
       b = { a = 2 } 
    }

i.e. the { is the left-most token.

EDIT: One off-site line starts with the { therefore you need to indent at least as much as the { the line break after is not mandatory. And the second warning is because of the same reason.

Spec says:

Other structured constructs also introduce offside lines at the following places:

  • The column of the first token of a (, { or begin token.

Why do you decide that offside line should be introduced by the token after the { when spec says that it should be the { itself?

NOTE: I agree that phrase "first token of ...token " sounds confusing. More likely it should be "first character of ...token" as this is applicable to begin\end case (offside line is introduced by the column of 'b' character)

begin
 begin
end // possible incorrect indentation: this token is offside of the context started at (2,2)
end

Having two warnings for the same position looks like a bug.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top