Я хочу написать общий код для разных типов без создания одного базового типа для него. Его типы реализуют несколько интерфейсов, которые нужны общему коду. Это способ или он не подходит для модели f # type?
type IInterface1 =
abstract member id :string
type IInterface2 =
abstract member weight :float
type A (id, weight) =
interface IInterface1 with member x.id = id
interface IInterface2 with member x.weight = weight
type B (id, weight) =
interface IInterface1 with member x.id = id
interface IInterface2 with member x.weight = weight
type Common<'T when 'T :> IInterface1 and 'T :> IInterface2> (o :'T) =
interface IInterface1 with member x.id = o.id
interface IInterface2 with member x.weight = o.weight
type LBranch<'T> (root :'T) =
member val root = root
member val branch = [root] :'T list with get, set
member x.add item = x.branch <- item :: x.branch; x
member x.head = match x.branch with h :: _ -> h | _ -> failwith "LevelingTree corrupt"
let a, b = A("1", 10.0), B("2", 100.0)
let ca, cb = Common(a), Common(b)
LBranch(ca).add(cb) // Common<B> is not compatible with Common<A>
Простое решение, которое я нашел, не хорошо, но работает:
type Common (o :obj) =
interface IInterface1 with member x.id = match o with :? IInterface1 as o -> o.id | _ -> failwith ""
interface IInterface2 with member x.weight = match o with :? IInterface2 as o -> o.weight | _ -> failwith ""