既存のコードをよりモノディックなアプローチにリファクタリングしようとしています。既存のコードには、 や などのインターフェイスと数値が含まれていIXInterface
ます。数値はデフォルトですでに持っており、インターフェイスにはプロパティ gettor としてそれがありますが、そうではありません。1 つの方法は bool と string をインターフェイスでラップすることですが、これは面倒です。int
bool
Zero
bool
string
私は、F# 言語が数値の型を拡張できるかどうかを考えました。おそらく、特定の状況では、文字列とブール値の型も拡張できるでしょう。
module MyZero =
let inline get_zero () : ^a = ((^a) : (static member get_Zero : unit -> ^a)())
type System.String with
static member get_Zero() = System.String.Empty
type XR<'T when 'T : (static member get_Zero : unit -> 'T)> =
| Expression of (SomeObj -> 'T)
| Action of (int -> 'T)
| Value of 'T
| Empty
member inline this.Execute(x: SomeObj) : 'T =
match this with
| Value(v) -> v
| Expression(ex) -> ex x
| Action(a) -> a x.GetLocation
| Empty -> get_zero()
static member map f x=
match x with
| XR.Empty -> XR.Empty
| XR.Value v -> XR.Value <| f v
| XR.Action p -> XR.Action <| fun v -> f (p v)
| XR.Expression e -> XR.Expression <| fun x -> f (e x)
// etc
上記は、文字列またはブール値で使用しない限り、正常にコンパイルされます。
type WihtBool = XR<int> // succeeds
type WihtBool = XR<IXInterface> // succeeds
type WihtBool = XR<bool> // fails
type WithString = XR<string> // fails
エラーは明確で正しいです(明らかな理由で認識されない拡張メソッドがあります)、それを取り除くための邪魔にならない方法がわかりません:
「型 bool は演算子 'get_Zero' をサポートしていません」
で失敗します 「型文字列は演算子 'get_Zero' をサポートしていません」で失敗します