F#中的mixin或trait

Pau*_*icz 9 f# functional-programming

有没有办法在Ruby中实现mixin或在F#中实现Scala中的特性?

我想要的是基本上将一个模块复制到另一个模块,以便它共享其他模块功能但是关闭以进行修改.或者,一个OOP的思考方式,我想要多重继承,除了父对象不能被修改.

Dan*_*iel 14

您可以滥用inline和成员约束来进行鸭子打字,这可以获得mixins的一些好处.例如,您可以翻译此Ruby代码(取自本教程):

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"
Run Code Online (Sandbox Code Playgroud)

对此:

type Phonograph(id, name) =
  member x.Id : int = id
  override x.ToString() = name

type EightTrack(id, name) =
  member x.Id : int = id
  override x.ToString() = name

module Debug =
  let inline whoAmI x =
    sprintf "%s (%d) : %s" 
      (^T : (member GetType : unit -> Type) x).Name
      (^T : (member Id : int with get) x)
      (^T : (member ToString : unit -> string) x)

let ph = Phonograph(537766170, "West End Blues")
let et = EightTrack(537765860, "Surrealistic Pillow")

Debug.whoAmI ph //"Phonograph (537766170) : West End Blues"
Debug.whoAmI et //"EightTrack (537765860) : Surrealistic Pillow"
Run Code Online (Sandbox Code Playgroud)

与不需要公共基类或接口的扩展方法相比,它具有(可论证的)优势.关于您之前关于该open关键字的问题,您可以定义几个模块whoAmI,open最后一个模块将影响前一个模块.通过这种方式,您可以"混合"您想要的模块.F#核心库使用与已检查运算符类似的方法.