什么是“可插拔多态”并且我如何从中受益?

90
在他的演讲Simple Made Easy中,Rick Hickey谈到了“多态菜单”(视频约在30:00处)。在同样的上下文中,他还提到了Haskell的类型类(Type Classes)和Clojure的多方法(Multi-Methods)(以及协议)。
由于我对这些概念不太熟悉,我想了解它在追求简洁性时的实用性。我特别感兴趣的是在Scala中应用这个概念的任何示例或展示。
1个回答

47
您可以将 Polymorphism a la carte 视为 按需多态性
Clojure社区为术语 Polymorphism a la carte 感到自豪,因为Clojure支持多种多态性策略。其中一些包括:
  • 基于原型的多态性

  • 继承多态性

    这是Java使用的多态性策略。Clojure通过代理来支持此功能。在执行Java互操作时非常有用。

  • 协议

    对于Clojure而言,协议就像Haskell中的TypeClass一样。

  • 多方法

    虽然协议基于第一个参数的类型提供多态分派,但多方法要灵活得多,可以根据方法(任何)参数的任何函数进行分派。

Polymorphism a la carte 的意思是“选择最适合您情况的任何多态性策略。它们都在您的工具箱中。”
您可以使用隐式实现 TypeClass 模式在Scala中。如果您想要真实世界的例子,请阅读Scalaz源代码。Scala不支持语言级别的多方法,但我想在即将推出的2.10宏的帮助下可能是可能的。
至于好处,高级多态性策略,例如TypeClass和Multimethod,可以帮助解决表达式问题

“目标是通过案例定义数据类型,在不重新编译现有代码的情况下添加新案例到数据类型并添加新函数覆盖数据类型,同时保留静态类型安全(例如,没有强制转换)”。

顺便说一下,这个问题太大了,无法在一个StackOverflow问题中解决。我的建议是先熟悉这些概念,然后你就会理解它们的用途。


1
非常微小的问题,但如果“协议基于第一个参数的类型提供多态分派”,那么它们就不对应于Haskell类型类。类型类实例可以在任何东西上“分派”(您甚至可以在类型类的实例中具有返回值的零参数类型函数,例如read,并且期望返回值的类型将确定使用哪个实例)。 - Ben
1
当然,read需要一个参数。我写这个时可能脑子不太清醒。mempty是我所说的例子之一。但是,read会根据其预期的返回类型进行分派。 - Ben
“[...] 目标是通过案例定义数据类型,其中可以向数据类型添加新案例和新函数 [...]”。这里所说的“case”是什么意思? - Abdull

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接