Search code examples
classsyntaxf#verbose

F# verbose syntax and class definition problem


I'm baffled by the fsharp-error given for following code in test.fsx:

let Kasper = "Kasper" in printfn "%A" Kasper
type student (name: string) =
  class
    member this.name = name
  end
let aStudent = student Kasper in printfn "%A" aStudent.name

which gives the following error,

% fsharpc test.fsx && mono test.exe
Microsoft (R) F# Compiler version 10.2.3 for F# 4.5
Copyright (c) Microsoft Corporation. All Rights Reserved.

/Users/sporring/Desktop/test.fsx(2,1): error FS0010: Unexpected keyword 'type' in implementation file
%

I have found the following solutions:

  • move the printfn "%A" Kasper.name; to a new line
  • move the whole construction let Kasper = "Kasper" in printfn "%A" Kasper below the type definition
  • convert it all to lightweight syntax

So it seems, that I don't understand the scope of the let-in expression. Would someone please help me understand why the original code fails to compile? Thanks.


Solution

  • The verbose syntax of F# is odd and there is a good reason why it's discouraged :-).

    The let .. in .. construct is an expression, but the top-level in a module (which is what you need when you also want to use type) behaves differently. At the module level, you can use let to define top-level values, but this is not let .. in .. expression but rather a declaration let <pat> = <expr>. You can also use the do keyword at the top-level if you want to run some code when the module is initialized, which is written as do <expr>. So, to make your example work, you can use:

    #light "off"
    let Kasper = "Kasper" do printfn "%A" Kasper
    type student (name: string) =
      class
        member this.name = name
      end
    do let aStudent = student Kasper in printfn "%A" aStudent.name
    

    To show more options, I write the first let as a top-level declaration, but the aStudent value is defined as a local binding in a do block.