Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to support structurally-typed in a nominal-typed language?

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?

like image 867
MiP Avatar asked Jan 05 '23 04:01

MiP


1 Answers

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#.

like image 57
Tomas Petricek Avatar answered Jan 13 '23 14:01

Tomas Petricek