11

This is allowed:

type Test = class end

[<CompilationRepresentation (CompilationRepresentationFlags.ModuleSuffix)>]
module Test = begin end

But this not:

[<CompilationRepresentation (CompilationRepresentationFlags.ModuleSuffix)>]
module Test = begin end

type Test = class end

Why?

In the second case, the error is: Duplicate definition of type or module 'Test'.

I'd love to be able to define some public [<Literal>] constants that are required for a type and important for users of the type inside a module with the same name.

Nikon the Third
  • 2,771
  • 24
  • 35
  • I don't see anything in the spec about a required order, so my guess is it's a bug. – Daniel Jul 10 '14 at 20:27
  • would something like "module Test_Literals", and then "open Test_Literals" prior to type Test do the trick? – sgtz Jul 11 '14 at 03:46

1 Answers1

14

You can open the type declaration, close it and re open later, something like this:

type Test = class end

[<CompilationRepresentation (CompilationRepresentationFlags.ModuleSuffix)>]
module Test =
    [<Literal>]
    let myLiteral = "myLiteral"

type Test with
    static member test = ()

I use this trick all the time ;)

Gus
  • 25,839
  • 2
  • 51
  • 76
  • That's a neat trick. Fixing a duplicate definition error by introducing another duplicate definition... well done, sir! But I guess it only works with type extensions? Nevertheless, this is totally usable in my case... – Nikon the Third Jul 11 '14 at 19:39
  • 3
    @NikontheThird it looks like a type extension but it is not. As long as it is in the same file the F# compiler puts everything together. – Gus Jul 11 '14 at 21:24
  • @Gustavo thanks for the nice trick, however it doesn't work when "Test" is a record type..which I do find needed occasionally. – trek42 Aug 10 '14 at 14:37