2017-09-17 12 views
2

このコードは、別のメンバがfmapをOptionとChoiceでコンパイルして完全に動作するように提案していますが、警告があります。 。 「Functor」の下の最終行:F#静的メンバの制約を理解する(一般的な警告より小さく構成する)

この構成では、コードが一般よりも小さくなります。型変数 'bはFunctorに制約されています。

type Functor = Functor 
    with 
    static member FMap (Functor, mapper : 'T -> 'U, opt : Option<'T>) : Option<'U> = 
     Option.map mapper opt 
    static member FMap (Functor, mapper : 'T -> 'U, ch : Choice<'T, _>) : Choice<'U, _> = 
     match ch with 
     |Choice1Of2 v -> Choice1Of2 (mapper v) 
     |Choice2Of2 v -> Choice2Of2 v 

let inline fmap (f : ^c -> ^d) (x : ^a) = 
    ((^b or ^a) : (static member FMap : ^b * (^c -> ^d) * ^a -> ^e) (Functor, f, x)) 

この種の意味は、^ bは常にFunctorでなければなりません。

この警告に対処するコードを再調整したいが、失敗している。

この目的のために、なぜ^ bは常にFunctorになるため、^ aだけでなく(^ bまたは^ a)が必要なのでしょうか。私は、(^ bまたは^ a)構文なしのコンパイル版を手に入れることができませんでした。

さらに、Functorの結合ケースをまったく通過させる必要があるのはなぜですか。繰り返しますが、何か私は理解できず、回避することができませんでした。

任意の明瞭さをお確かめください。

あなたは、単に #nowarn "0064"を追加することによって、または、このような内部呼び出し機能追加することで警告を解決することができ

答えて

1

let inline fmap (f :'c->'d) (x : 'a) : 'e = 
    let inline call (mthd : ^B, x : ^A) = 
     ((^B or ^A) : (static member FMap: _ * (^c -> ^d) * ^A -> ^e) (mthd, f, x)) 
    call (Unchecked.defaultof<Functor>, x) 

コールまでに解決されていない追加の型の変数を追加し、型推論のためにこの方法をBがa、Aがa、BがFunctorであることは明らかではない。

Functor型の静的メソッド(OptionやChoiceなどの既存の型)を検索する必要があるため、^Aで表される将来の型定義のために、^B or ^Aが必要です。後で追加することができます。コードのようなもの:まだ

type MyType<'a> = MyType of 'a with 
    static member FMap (Functor, mapper, MyType a) = MyType (mapper a) 

とで動作します:(観察とtを試みることによって最後に

> fmap string (MyType 4) ;; 
val it : MyType<string> = MyType "4" 

それは、この技術は先駆者と実験プロジェクトで洗練されたことに言及worths o +演算子の制約を模倣しています)は、F#+という汎用モジュールの一部です。したがって、「デフォルトの実装」を含むcomplex examples thereを見つけることができます。

関連する問題