包装类型成员

see*_*equ 2 generics f# wrapper

我一直在尝试实现一个调用类型成员的泛型函数.我发现使用内联可以实现这一点.它没有帮助,所以我试图实现一个接口,如下所示:

type Wrappable<'a, 'b> =
    interface
      abstract Wrap : ('b -> 'b) -> 'a
    end

type StateType =
    State of Scene * Cash | Exit
    interface Wrappable<StateType, Scene * Cash> with
        member this.Wrap f =
            match this with
            | Exit -> Exit
            | State (scene, cash) -> f (scene, cash) |> State

let inline wrap f (o:Wrappable<_, _>) = o.Wrap f
Run Code Online (Sandbox Code Playgroud)

这非常有效,给出了类型输出

type Wrappable<'a,'b> =
  interface
    abstract member Wrap : ('b -> 'b) -> 'a
  end
type StateType =
  | State of Scene * Cash
  | Exit
  with
    interface Wrappable<StateType,(Scene * Cash)>
  end
val inline wrap : f:('a -> 'a) -> o:Wrappable<'b,'a> -> 'b
Run Code Online (Sandbox Code Playgroud)

不过,我发现这种方式非常难看.我的问题是:有没有更好的方法将一个成员包装在一个函数中?

Car*_*ten 5

这是你如何使用我提到的静态解析类型参数来做到这一点:

type StateType =
    State of int * string | Exit
        member this.Wrap f =
            match this with
            | Exit -> Exit
            | State (scene, cash) -> f (scene, cash) |> State

let inline wrap f (o : ^a) = (^a : (member Wrap : (^b -> ^b) -> ^a) (o, f))
Run Code Online (Sandbox Code Playgroud)

我用的int * string,因为我不知道你不SceneCash,想测试一下:

> let x = State (5,"Hallo");;

val x : StateType = State (5,"Hallo")

> let f (x,y) = (x+x,y);;

val f : x:int * y:'a -> int * 'a

> wrap f x;;

val it : StateType = State (10,"Hallo")
Run Code Online (Sandbox Code Playgroud)