What you are trying to do is possible. You can emulate models in F #, as Thomas said, perhaps this is not as idiomatic as in Haskell. I think in your example you mix type classes with duck type, if you want to go to typeclasses type approach, don't use members, use functions and static members instead.
So your code might be something like this:
type Print = Print with static member ($) (_Printable:Print, x:string) = printfn "%s" x static member ($) (_Printable:Print, x:int ) = printfn "%d" x // more overloads for existing types let inline print p = Print $ p type Print with static member inline ($) (_Printable:Print, (a,b) ) = print a; print b print 5 print ((10,"hi")) print (("hello",20), (2,"world")) // A wrapper for Int (from your sample code) type PrintableInt = PrintableInt of int with static member ($) (_Printable:Print, (PrintableInt (x:int))) = printfn "%d" x let (!) x = PrintableInt(x) let x = (!1,!2),(!3,!4) print x // Create a type type Person = {fstName : string ; lstName : string } with // Make it member of _Printable static member ($) (_Printable:Print, p:Person) = printfn "%s, %s" p.lstName p.fstName print {fstName = "John"; lstName = "Doe" } print (1 ,{fstName = "John"; lstName = "Doe" })
Note. I used the operator to avoid writing constraints manually, but in this case you can also use a named static member. Read more about this method here .
source share