Interface 使用泛型lambda处理接口集合的方法
我目前正在尝试使用F#进行试验,我正在努力解决如何最好地处理以下类型的场景:Interface 使用泛型lambda处理接口集合的方法,interface,f#,Interface,F#,我目前正在尝试使用F#进行试验,我正在努力解决如何最好地处理以下类型的场景: [<Interface>] type IStuff<'a> = abstract member Update: 'a -> 'a type Stuff1<'a> = { Pos : int Sprite : string Temperature : float UpdateBehaviour : 'a -> 'a }
[<Interface>]
type IStuff<'a> =
abstract member Update: 'a -> 'a
type Stuff1<'a> = {
Pos : int
Sprite : string
Temperature : float
UpdateBehaviour : 'a -> 'a
} with
interface IStuff<'a> with
member this.Update p =
this.UpdateBehaviour p
static member New f = {
Pos = 0
Sprite = "Sprite"
Temperature = 0.0
UpdateBehaviour = f
}
type Stuff2<'a> = {
Pos : int
UpdateBehaviour : 'a -> 'a
} with
interface IStuff<'a> with
member this.Update p =
this.UpdateBehaviour p
static member New f = {
Pos = 0
UpdateBehaviour = f
}
这显然不起作用,因为编译器确定这两种类型明显不同,Stuff1
为类型'a
,而Stuff2
为类型'b
我也可以这样做
let stuffArr< 'T when 'T :> IStuff<'T>> = [|
Stuff1.New<_> (fun p -> printfn "s1"; p)
Stuff2.New<_> (fun p -> printfn "s2"; p)
|]
let stuffArr : obj list = [
Stuff1.New<_> (fun p -> printfn "p1"; p)
Stuff2.New<_> (fun p -> printfn "p2"; p)
]
let iterateThrough (l : obj list) =
l
|> List.map (fun p ->
let s = p :?> IStuff<_>
s.Update p)
let stuffArr:obj list=[
Stuff1.新建(乐趣p->printfn“p1”;p)
Stuff2.新建(乐趣p->printfn“p2”;p)
]
让iterateThrough(l:obj列表)=
L
|>List.map(乐趣p->
设s=p:?>IStuff
s、 更新(p)
这很明显,但正如你们现在可能看到的,我基本上关闭了类型系统,我正在做一个动态的向下转换,坦率地说,这让我感到害怕
那么,有没有更好的方法来实现这一点?提前谢谢 有很多方法可以让你对现有的结构进行更多的检查,但这些方法都不是很好。然而,我认为最根本的问题是,您正试图将F#用作一种面向对象的语言。如果您使用更实用的设计,这将看起来更好 我将
东西定义为与不同种类的东西有区别的结合:
type Stuff =
| Stuff1 of pos:int * sprite:string * temperature:float
| Stuff2 of pos:int
let stuffArr = [
Stuff1(0, "Sprite", 0.0)
Stuff2(0)
]
更新操作将只是一个函数,它使用模式匹配来处理您拥有的两种不同类型的内容:
let update stuff =
match stuff with
| Stuff1 _ -> ...
| Stuff2 _ -> ...
结果是,您只需使用list.map
,即可更新所有内容并获得新列表:
List.map update stuffArr
我有种感觉,你上面展示的内容可能与你实际要做的事情不一样复杂。如果是这样,Tomas的解决方案可能太简单,您无法使用。如果您有某种原因喜欢使用上面描述的界面,您可以如下定义stuffArr
let stuffArr : IStuff<_>[] = [|
Stuff1.New<int> (fun p -> printfn "s1"; p)
Stuff2.New<int> (fun p -> printfn "s2"; p)
|]
或者使用内置的选项
类型
let stuffArr : IStuff<_>[] = [|
Stuff1.New<Choice<string, int>> (fun p -> printfn "s1"; p)
Stuff2.New<Choice<string, int>> (fun p -> printfn "s2"; p)
|]
let-stufgarr:IStuff[]=[|
Stuff1.新建(趣味p->printfn“s1”;p)
Stuff2.新建(乐趣p->printfn“s2”;p)
|]
Ok。如果我正在创建某种类型的库,并且我希望用户以某种组件式的方式创建自己的类型,那么就会出现问题。但这可能是这个特定问题的正确答案,谢谢!
let stuffArr : IStuff<_>[] = [|
Stuff1.New<Choice<string, int>> (fun p -> printfn "s1"; p)
Stuff2.New<Choice<string, int>> (fun p -> printfn "s2"; p)
|]