mixin or trait in F#
f#, functional-programming
Solution
You can abuse `inline` and member constraints to do duck typing, which gets you some of the benefits of mixins. For example, you could translate this Ruby code (taken from this tutorial):
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"
to this:
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"
It has the (arguable) advantage over extension methods of not requiring a common base class or interface. Regarding your previous question about the `open` keyword, you could have several modules defining `whoAmI` and the one `open`ed last will shadow previous ones. In that way you can sort of "mix in" which module you want. The F# core library uses a similar approach with checked operators.
Problem
Is there a way to achieve a mixin in Ruby or a trait in Scala in F#? What i want is to basically copy one module into another so that it shares the other modules functionality but is closed for modification. Or, an OOP way of thinking about it, I want multiple inheritance except that the parent object can not be modified.