In F#, Nominative or Structural?, the answer said that I can trick F# to work like a structurally-typed language via some exotic mechanisms. How can I do so?
The "exotic mechanism" that the previous answer refers to is probably statically resolved type parameters. This lets you write functions that take object of any type that has some specific member. For example, you can write sayHello
function that will work with any object that has a Name
member of type string
:
let inline sayHello (any : ^T) =
let name = (^T : (member Name : string) any)
printfn "Hello %s" name
This will now work with two types that are nominally unrelated:
type Person(name:string) =
member x.Name = name
type Animal(name:string) =
member x.Name = name
sayHello (Person("Tomas"))
sayHello (Animal("Bunny"))
That said, F# is primarily a nominally typed language and so relying on static member constraints too much would be unidiomatic. It will make your code look bad and you'll likely hit limitations of the mechanism. It is a nice feature for some limited use cases, but it's not a primary abstraction mechanism in F#.
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