I have the following working F# source file
namespace Namspa1
[<AutoOpen>]
module M1 =
let [<Literal>] constant1 = "Hello, "
type Greeter(name) =
member x.Greet() = sprintf "%s%s" constant1 name
module M2 =
let greet name = Greeter(name).Greet()
This works but what I want is define the function greet in the same module M1 where constant1 is defined. In other words, using only one file I want to obtain
Namspa1.M1.constant1
Namspa1.Greeter
Namspa1.M1.greet //not Namspa1.M2.greet
If I try to change the greet function definition as
module M1 =
let greet name = Greeter(name).Greet()
I get an Duplicate definition error for M1.
How do I do it?
EDIT
It's been suggested that using attribute CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix) fixes the Duplicate definition error, which is true so thanks for this.
However my request is about extending M1. I want to be able to use M1.greet as if the function was defined in M1. For example, if I try to use the definitions externally (e.g. another source file), I can use M2.greet, so I want to use M1.greet, which is not possible with the attribute
This is possible by setting the CompilationRepresentation
attribute to CompilationRepresentationFlags.ModuleSuffix
. Extending a module like this is not an intended use case, so the second module definition needs to be moved to a separate source file.
First file:
namespace Namspa1
[<AutoOpen>]
module M1 =
let [<Literal>] constant1 = "Hello, "
type Greeter(name) =
member x.Greet() = sprintf "%s%s" constant1 name
Second file:
namespace Namspa1
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module M1 =
let greet name = Greeter(name).Greet()
Technically, it generates a module named M1Module, which will affect access from other .NET languages.
What you want to achieve is possible by using a recursive namespace. Notice the rec
keyword when declaring the namespace.
namespace rec Namspa1
[<AutoOpen>]
module M1 =
let [<Literal>] constant1 = "Hello, "
let greet name = Greeter(name).Greet()
type Greeter(name) =
member x.Greet() = sprintf "%s%s" constant1 name
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With