F#のジェネリクスに制約をつけて、型パラメータに使える型を制限することができます。
それを使って、構造的部分型(structural subtyping)みたいな動きをさせてみようと思います。
structuralSubtyping.fs
// target : exec メソッドを持つオブジェクト
// num : exec メソッドに渡す値
let inline exec< ^T when ^T : (member exec : int -> string)> target num =
(^T : (member exec : int -> string) (target, num))
// exec メソッドを持つインターフェイス
type IExec =
abstract exec : int -> string
// IExec インターフェイスを実装するクラス
type Hoge() =
interface IExec with
member this.exec num = (num * 2).ToString()
// exec メソッドを持つクラス
type Fuga() =
member self.exec num = (num * (-1)).ToString()
let hoge = Hoge()
exec (hoge :> IExec) 2 // #=> val it : string = "4"
let fuga = Fuga()
exec fuga 2 // #=> val it : string = "-2"
個人的には Explicit member constraint の勉強になったので良かったですね。