Reputation: 34099
I have following trait:
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]
As you can see, there is a fold
method implementation.
I could move the fold
method into a companion object as follow:
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)
}
}
What is more convenient pattern, the first or second example and in which situation?
Upvotes: 0
Views: 63
Reputation: 170839
I'd prefer the first (or the modification in Tomasz Perek's answer). The second should be changed to
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)
}
so that the compiler already knows A
and B
by the time it gets to type-checking the error
and success
parameters.
Upvotes: 0
Reputation: 409
The latter will probably not work as you intend, since this
in that case is the object Sum
not the instance of either Failure
or Success
.
Anyway, I'd move the implementations to case classes:
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)
}
Upvotes: 1
Reputation: 7564
The second one doesn't work, since this is pointing to the Sum companion object, and the type variables A and B aren't defined.
Therefore use the first pattern!
Upvotes: 0