选择要使用的模式

时间:2017-04-04 09:17:49

标签: scala

我有以下特质:

sealed trait Sum[+A, +B] {
  def fold[C](error: A => C, success: B => C): C =
    this match {
      case Failure(v) => error(v)
      case Success(v) => success(v)
    }
}
final case class Failure[A](value: A) extends Sum[A, Nothing]
final case class Success[B](value: B) extends Sum[Nothing, B]

如您所见,有一个fold方法实现。

我可以将fold方法移动到一个伴随对象中,如下所示:

sealed trait Sum[+A, +B]
final case class Failure[A](value: A) extends Sum[A, Nothing]
final case class Success[B](value: B) extends Sum[Nothing, B]

object Sum{
    def fold[A, B, C](s: Sum[A,B], error: A => C, success: B => C): C =
        s match {
          case Failure(v) => error(v)
          case Success(v) => success(v)
        }
}

什么是更方便的模式,第一个或第二个例子以及在哪种情况下?

3 个答案:

答案 0 :(得分:1)

后者可能无法按预期工作,因为在这种情况下this是对象Sum而不是FailureSuccess的实例。 无论如何,我将实现移到案例类:

   case class Failure[A](value: A) extends Sum[A, Nothing] {
      def fold[C](error: A => C, success: B => C): C = error(value)
   }

   case class Success[A](value: B) extends Sum[A, Nothing] {
      def fold[C](error: A => C, success: B => C): C = success(value)
   }

答案 1 :(得分:0)

第二个不起作用,因为它指向Sum伴随对象,并且未定义类型变量A和B.

因此使用第一个模式!

答案 2 :(得分:0)

我更喜欢第一个(或Tomasz Perek的答案中的修改)。第二个应该改为

def fold[A, B, C](s: Sum[A,B])(error: A => C, success: B => C): C =
    s match {
      case Failure(v) => error(v)
      case Success(v) => success(v)
    }

以便编辑器在对AB参数进行类型检查时已经知道errorsuccess