gpt4 book ai didi

scala - 对象-功能阻抗不匹配

转载 作者:行者123 更新时间:2023-12-02 20:44:12 25 4
gpt4 key购买 nike

在 OOP 中,与接口(interface)对话而不是与实现对话是一个很好的做法。因此,例如,您编写类似的内容(通过 Seq 我的意思是 scala.collection.immutable.Seq :)):

// talk to the interface - good OOP practice
doSomething[A](xs: Seq[A]) = ???

不是如下所示:

// talk to the implementation - bad OOP practice
doSomething[A](xs: List[A]) = ???

但是,在纯函数式编程语言(例如 Haskell)中,您没有子类型多态性,而是通过类型类使用临时多态性。例如,您有列表数据类型和列表的单子(monad)实例。你不需要担心使用接口(interface)/抽象类,因为你没有这样的概念。

在混合语言中,比如 Scala,你同时拥有类型类(实际上是通过一种模式,而不是像 Haskell 中的一等公民,但我离题了)和子类型多态性。当然,在 scalaz 、cats 等中,您拥有具体类型的单子(monad)实例,而不是抽象类型的单子(monad)实例。

最后一个问题:考虑到 Scala 的这种混合性,您是否仍然尊重 OOP 规则来与接口(interface)对话,或者只与具体类型对话以直接利用仿函数、单子(monad)等,而无需每当需要使用它们时转换为具体类型?换句话说,即使您想拥抱 FP 而不是 OOP,在 Scala 中与接口(interface)对话仍然是良好的实践吗?如果没有,如果您选择使用 List,后来您意识到 Vector 会是更好的选择,该怎么办?

P.S.:在我的示例中,我使用了一个简单的方法,但相同的推理也适用于用户定义的类型。例如:

case class Foo(bars: Seq[Bar], ...)

最佳答案

我在这里要攻击的是你的“具体与界面”的概念。这样看:每种类型都有一个接口(interface),即术语“接口(interface)”的一般含义。 “具体”类型只是一种限制情况。

那么让我们从这个角度来看看 Haskell 列表。列表的接口(interface)是什么?好吧,列表是一种代数数据类型,所有这些数据类型都具有相同的接口(interface)和契约的通用形式:

  1. 您可以根据类型的参数数量和参数类型,使用其构造函数构造该类型的实例;
  2. 您可以通过根据类型的参数数量和参数类型匹配其构造函数来观察该类型的实例;
  3. 构造和观察是相反的 - 当您针对某个值进行模式匹配时,您得到的正是放入其中的内容。

如果您从这些角度来看,我认为以下规则在任一范例中都非常有效:

  • 选择其接口(interface)和合约完全符合您的要求的类型。
    • 如果他们的契约弱于您的要求,那么他们就不会维护您需要的不变量;
    • 如果他们的契约(Contract)比您的要求更严格,您可能会无意中将自己与“额外”细节联系在一起,并限制您以后更改计划的能力。

因此,您不再询问类型是“具体”还是“抽象”,而只需询问它是否符合您的要求。

关于scala - 对象-功能阻抗不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37116394/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com