类型成员的包装器
Wrapper for a type member
我一直在尝试实现调用类型成员的泛型函数。我发现这应该可以通过使用内联来实现。它没有帮助,所以我尝试实现一个接口,如下所示:
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
这很好用,输出类型
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
不过,我觉得这种方式非常丑陋。我的问题是:有没有更好的方法将成员包装在函数中?
这是使用我提到的statically resolved type parameters的方法:
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
,因为我不知道你的Scene
和Cash
,想测试一下:
> 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")
为什么不使用运算符? 隐式解析的符号运算符 将被编译为静态 成员约束调用表达式 无论如何,没有丑陋的语法。该语言功能依赖于静态解析的类型参数。参见 F# spec.
的 14.2.2(最后一行)
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)
我一直在尝试实现调用类型成员的泛型函数。我发现这应该可以通过使用内联来实现。它没有帮助,所以我尝试实现一个接口,如下所示:
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
这很好用,输出类型
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
不过,我觉得这种方式非常丑陋。我的问题是:有没有更好的方法将成员包装在函数中?
这是使用我提到的statically resolved type parameters的方法:
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
,因为我不知道你的Scene
和Cash
,想测试一下:
> 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")
为什么不使用运算符? 隐式解析的符号运算符 将被编译为静态 成员约束调用表达式 无论如何,没有丑陋的语法。该语言功能依赖于静态解析的类型参数。参见 F# spec.
的 14.2.2(最后一行)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)