So as far as I understand, the convention is to define your type, and then define a module with the same name after it with the functions that operate on the type.
I'm trying to do that so I have this code
namespace Rand
type ImmutableRandom
module ImmutableRandom =
open System
val fromSeed : int -> ImmutableRandom
val int : ImmutableRandom -> int
val intInRange : ImmutableRandom -> int -> int -> int
val double : ImmutableRandom -> double
val next : ImmutableRandom -> ImmutableRandom
I'm getting the error that ImmutableRandom (the name of the module is underlined) is redefining a type or a module.
In the very same project, the identical setup works for a different type, with the only difference being that that type has a generic parameter, while ImmutableRandom doesn't.
What am I doing wrong?
Use the CompilationRepresentation
attribute on your module so that it has the same name in source, but not in IL:
namespace Rand
type ImmutableRandom
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module ImmutableRandom =
open System
val fromSeed : int -> ImmutableRandom
val int : ImmutableRandom -> int
val intInRange : ImmutableRandom -> int -> int -> int
val double : ImmutableRandom -> double
val next : ImmutableRandom -> ImmutableRandom
This will cause the module to be named ImmutableRandomModule
in IL (and consequently from languages other than F#). This has a few advantages over static members, which are well summarized in this answer: F# code organization: types & modules
This works if the type is generic. Otherwise, there is ambiguity that the compiler cannot resolve on its own.
If you really feel the need to do this with a non-generic type, define all the functions as static members on the type. A bit less elegant, but you get the same surface API.
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