2016-06-21 7 views
3

多型map(Functor)を作成しようとしていますが、このタイプのエラーが停止します。マップ関数をインライン化する(Functor)

は、次のタイプ

type Result<'TSuccess, 'TError> = 
    | Success of 'TSuccess 
    | Error of 'TError list 
    with 
    member this.map f = 
     match this with 
      | Success(s) -> Success(f s) 
      | Error(e) -> Error e 

と、このインライン関数

let inline (<!>) (f: ^A -> ^B) (t:^T) = 
    let map' = (^T : (member map : (^A -> ^B) -> ^T) (t, f)) 
    map' 

(fun x y -> x + y) <!> (Success 3);; 

が、私はこのエラーを取得し、この呼び出し元のコードを考えると

(fun x y -> x + y) <!> (Success 3);; 
--------------------------------^ 
/Users/robkuz/stdin(404,33): error FS0001: 
This expression was expected to have type 
'a -> 'b 
but here has type 
int 

これはなぜそうなのですか? ^Tは、
^T<('a->'b>)>である必要があります。これはF#ではとにかくできません。

btw。 (fun x -> x + 1) <!> (Success 3)のようなコールはうまく動作します

+0

nope!変化なし。 – robkuz

+0

'f'を単項として宣言していますが、バイナリ関数を渡しています。 '(fun x - > x + x)(成功3)'はどうでしょうか? – ildjarn

+0

[詳しい説明](http://nut-cracker.azurewebsites.net/blog/2011/11/15/typeclasses-for-fsharp/)です。 – Gustavo

答えて

3

おそらく私は何か明白が見当たりませんが、ちょっとした変更をしても<!>にはうまくいかないでしょうか?

type Result<'TSuccess, 'TError> = 
    | Success of 'TSuccess 
    | Error of 'TError list 
    with 
    member this.map (f : 'TSuccess -> 'T) = 
    match this with 
    | Success s -> Success (f s) 
    | Error e -> Error e 

let inline (<!>) (f : ^A -> ^B) (t : ^T) : ^U = 
    let map' = (^T : (member map : (^A -> ^B) -> ^U) (t, f)) 
    map' 

[<EntryPoint>] 
let main argv = 
    let w = (fun x y -> x + y) <!> Success 3 
    let x = (fun x -> x 2) <!> w 
    printfn "%A" x // Prints "Success 5" 
    0 
+0

うわー。ええ、追加の '^ T'はトリックをします – robkuz

+0

多分あなたはこの1つを試してみたいですか? ;-) http://stackoverflow.com/questions/37949413/how-to-do-a-applicative-in-f – robkuz

+0

あなたはすでに回答があるようですが、同じ考え方もあります。 – FuleSnabel

関連する問題