混合或特征于F#
有没有办法在Ruby中实现mixin,或者在F#中实现Scala的trait混合或特征于F#,f#,functional-programming,F#,Functional Programming,有没有办法在Ruby中实现mixin,或者在F#中实现Scala的trait 我想要的基本上是将一个模块复制到另一个模块中,这样它就可以共享其他模块的功能,但可以关闭以进行修改。或者,从面向对象的角度来看,我想要多重继承,但父对象不能修改 Ruby mixin最好用.NET framework中的扩展方法(类型扩展)来模拟。我不认为F#有任何更接近混合、特征或多重继承的特殊语言特征 见这个问题: 以及以下描述: 为了提高速度,以下是MSDN上给出的示例: module MyModule1 =
我想要的基本上是将一个模块复制到另一个模块中,这样它就可以共享其他模块的功能,但可以关闭以进行修改。或者,从面向对象的角度来看,我想要多重继承,但父对象不能修改 Ruby mixin最好用.NET framework中的扩展方法(类型扩展)来模拟。我不认为F#有任何更接近混合、特征或多重继承的特殊语言特征 见这个问题: 以及以下描述: 为了提高速度,以下是MSDN上给出的示例:
module MyModule1 =
// Define a type.
type MyClass() =
member this.F() = 100
// Define type extension.
type MyClass with
member this.G() = 200
module MyModule2 =
let function1 (obj1: MyModule1.MyClass) =
// Call an ordinary method.
printfn "%d" (obj1.F())
// Call the extension method.
printfn "%d" (obj1.G())
您可以滥用
inline
和成员约束来进行duck键入,这可以让您获得mixin的一些好处。例如,您可以翻译此Ruby代码(摘自):
为此:
类型留声机(id、名称)=
成员x.Id:int=Id
重写x.ToString()=名称
输入EightTrack(id、名称)=
成员x.Id:int=Id
重写x.ToString()=名称
模块调试=
让我们来看看=
sprintf“%s(%d):%s
(^T:(成员GetType:unit->Type)x).名称
(^T:(成员Id:int和get)x)
(^T:(成员到字符串:单位->字符串)x)
让ph=留声机(537766170,“西区布鲁斯”)
let et=EightTrack(537765860,“超现实主义枕头”)
Debug.whoAmI ph/“留声机(537766170):西区布鲁斯”
Debug.whoAmI et/“EightTrack(537765860):超现实主义枕头”
与不需要公共基类或接口的扩展方法相比,它具有(有争议的)优势。关于您之前关于open
关键字的问题,您可以有几个模块定义whoAmI
,最后一个open
ed模块将覆盖前面的模块。通过这种方式,您可以排序“混合”您想要的模块。F#core库使用了类似的方法。有些相关:
module Debug
def whoAmI?
"#{self.type.name} (\##{self.id}): #{self.to_s}"
end
end
class Phonograph
include Debug
# ...
end
class EightTrack
include Debug
# ...
end
ph = Phonograph.new("West End Blues")
et = EightTrack.new("Surrealistic Pillow")
ph.whoAmI? » "Phonograph (#537766170): West End Blues"
et.whoAmI? » "EightTrack (#537765860): Surrealistic Pillow"