scala - 从函数式迁移到 OO 的问题

标签 scala haskell functional-programming oop

我习惯于使用函数式编程(主要是 Haskell),我从 OO(scala)开始。

我在翻译我的代码时遇到了麻烦。例如,这是我对 B-tree 的 Haskell 定义:

data BTree a = 
    Leaf
    |Node2 (BTree a) a (BTree a)
    |Node3 (BTree a) a (BTree a) a (BTree a)
    deriving (Eq,Read,Show) 

这很简单。我的树是空的,或者它有一个值并且是两棵树的父亲,或者它是三棵子树的父亲。

OO上有什么?我没有任何线索。我只是无法弄清楚我该如何以理智的方式做到这一点。

最佳答案

这里有一些很好的答案,但我认为他们都错过了展示你所缺少的观点的机会。所以,你已经证明了这一点:

data BTree a = 
    Leaf
    |Node2 (BTree a) a (BTree a)
    |Node3 (BTree a) a (BTree a) a (BTree a)
    deriving (Eq,Read,Show)

并询问您如何以面向对象的方式实现这一点。所以,这里是:

最重要的事情
trait Tree[A] {
  // not required because it is inherited from AnyRef
  // def equals(other: Any): Boolean

  // not required because it is inherited from AnyRef
  // def toString: String

  // does not belong in the object
  // def fromString(input: String): Tree[A]

  // Stuff that is missing but is needed
  def isEmpty: Boolean
  def value: Option[A]
  def subtrees: Seq[Tree[A]]
  def iterator: Iterator[A]
  def depthFirstIterator: Iterator[A]
  def breadthFirstIterator: Iterator[A]
}

所以,问题是这样的:当你谈到面向对象时,你有一个 BTree、一个手指树或任何其他不相关的树结构。事实上,它应该被隐藏起来。相关的是你可以用它做什么。

您在这样做时遇到了麻烦,因为您正在从不应该的方向准确地解决问题。

不那么重要的事情
sealed abstract class BTree[A] extends Tree[A]
object BTree {
  def apply[A](input: String): BTree[A] = { /* factory */ null.asInstanceOf[BTree[A]] }
  private case object Leaf extends BTree[Nothing] {
    // method implementation
  }
  private case class Node2[A](value: A, private one: BTree[A], private two: BTree[A]) extends BTree[A] {
    // method implementation
  }
  private case class Node3[A](value: A, private one: BTree[A], private two: BTree[A], private three: BTree[A]) extends BTree[A] {
    // method implementation
  }
}

现在在这里你实际上提供了一个实现,但是 BTree 的细节是完全隐藏的。您只能使用 Tree 的方法。已定义。

这是理想的面向对象架构:客户端依赖于接口(interface),数据结构是隐藏的。

关于scala - 从函数式迁移到 OO 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4348788/

相关文章:

scala - SBT 在 Artifactory Maven 存储库中找不到快照

haskell - Haskell 中的非树数据结构

python - 检查对象是否是字符串列表的列表?

scala - 如何以更实用的风格重写带有变量字段的 Scala 类?

scala - pyspark簇yarn中的spark-sftp jar出现错误

scala - 为什么 Kotlin 不允许在标识符中使用斜杠

haskell - 可以对公共(public)数据类型强制执行约束吗?

haskell - 用延续重写代码

haskell - 如何在不使用求和类型或副本的情况下创建异构数据类型列表

scala - 值 |@|不是 cats.data.Validated 的成员