То, что вы пытаетесь сделать, возможно.Вы можете эмулировать классы типов в F #, как сказал Томас, возможно, это не так идиоматично, как в Haskell.Я думаю, что в вашем примере вы смешиваете классы типов с типизацией утили, если вы хотите использовать подход классов типов, не используйте члены, вместо этого используйте функции и статические члены.:
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" })
Примечание. Я использовал оператор, чтобы избежать записи ограничений вручную, но в этом случае также возможно использовать именованный статический член.Подробнее об этой технике здесь .