Generics 类型成员的包装器

Generics 类型成员的包装器,generics,f#,wrapper,Generics,F#,Wrapper,我一直在尝试实现一个调用类型成员的泛型函数。我发现这应该可以通过使用inline实现。它没有帮助,所以我尝试实现一个接口,如下所示: type Wrappable<'a, 'b> = interface abstract Wrap : ('b -> 'b) -> 'a end type StateType = State of Scene * Cash | Exit interface Wrappable<StateTy

我一直在尝试实现一个调用类型成员的泛型函数。我发现这应该可以通过使用inline实现。它没有帮助,所以我尝试实现一个接口,如下所示:

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
类型可包装=
接口
抽象包装:('b->'b)->'a
结束
类型StateType=
现场状态*现金|退出
与可包装的接口
请记住这个=
与此匹配
|退出->退出
|状态(场景,现金)->f(场景,现金)|>状态
让内联包装f(o:Wrappable)=o.包装f
这非常有效,可以提供类型输出

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
类型可包装=
接口
抽象成员包装:('b->'b)->'a
结束
类型StateType=
|现场状况*现金
|出口
具有
接口可包装
结束
val内联包装:f:('a->'a)->o:Wrappable->'b

不过,我觉得这种方式很难看。我的问题是:有没有更好的方法将成员包装到函数中?

这就是使用我提到的:

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))
我使用了
int*string
,因为我不知道你的
场景
现金
,我想测试一下:

> 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")

为什么不使用操作员?隐式解析的符号运算符无论如何都将编译为静态成员约束调用表达式,没有难看的语法。该语言功能依赖于静态解析的类型参数。见第14.2.2节(最后一行)


你可能正在寻找(你可以用这些做一些令人印象深刻的事情)-我只是想知道你在这里想要完成什么-这只是通过
o
的类型来决定正确的
wrap
?你在函数中包装一个成员是什么意思?这里唯一的成员是
Wrap
,您为了实现您的目标而引入了它(IIUC)。。。因此,潜在的问题是:你的目标是什么?@MarkSeemann这是关于让'wrap'函数与每个具有成员
wrap
的类型一起工作。事实上,虽然语法在我看来有点不稳定,但我认为它仍然比在界面上瞎混要好得多。谢谢。是的,语法很糟糕-我每次尝试这样做时基本上都需要2-3个WTF(是
(o,f)
还是
(o f)
?…是
(member…(o)
还是
(member…(o))
等等。pp)我不喜欢添加不必要的操作符,尤其是当函数通常不与两个参数一起使用时。
type StateType =
    State of int * string | Exit
    static member ($) (this, f) =
        match this with
        | Exit -> Exit
        | State (scene, cash) -> f (scene, cash) |> State

type UnitType =
    | Etats of float * unit
    static member ($) (Etats (scene, ()), f) =
        f (scene, ()) |> Etats

let inline f (x,y) = (x+x,y)

let st = State (5,"Hallo")
st $ f   // val it : StateType = State (10,"Hallo")

let ut = Etats (5., ())
ut $ f   // val it : UnitType = Etats (10.0,null)