我正在尝试编写一个多态的map(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#中还是不可能的。

顺便说一句像(fun x -> x + 1) <!> (Success 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

09-10 05:56
查看更多