Skip to content

Instantly share code, notes, and snippets.

@Savelenko
Created September 25, 2023 09:06
Show Gist options
  • Save Savelenko/37a79561ae7369138111b51e17072440 to your computer and use it in GitHub Desktop.
Save Savelenko/37a79561ae7369138111b51e17072440 to your computer and use it in GitHub Desktop.
Polymorphic factory methods
type Factory<'T> = unit -> Option<'T>
type NoOptionFactory<'T> = unit -> 'T
type FactoryTests () =
member _.CanFactory () =
// Use the Option-returning factory
let factory : Factory<'T> = FactoryTests.FactoryFunction
let testString : Option<string> = factory ()
let testInt : Option<int> = factory ()
printfn $"Option-returning factory produced values {testString} and {testInt}"
// Actual output:
// Option-returning factory produced values Some(String) and Some(1)
// Use the non-Option factory
let factory : NoOptionFactory<'T> = FactoryTests.NonOptionFactoryFunction
// Note absence of type annotations compared to the above. This time the types will be "forced" by typed string
// interpolation.
let testString = factory ()
let testInt = factory ()
printfn $"Non-Option factory produced values %s{testString} and %d{testInt}"
// Actual output:
// Non-Option factory produced values String and 1
()
static member FactoryFunction<'T> () : Option<'T> = // Full type annotation including result type is required
if typeof<'T> = typeof<string> then
Some (box "String" :?> 'T)
elif typeof<'T> = typeof<int> then
Some (box 1 :?> 'T)
else
None
static member NonOptionFactoryFunction<'T> () : 'T =
if typeof<'T> = typeof<string> then
box "String" :?> 'T
elif typeof<'T> = typeof<int> then
box 1 :?> 'T
else
failwith "Type is not supported"
[<EntryPoint>]
let main argv =
(FactoryTests ()).CanFactory ()
0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment