在这种情况下你会使用类型 class 吗?
Would you use a type class in this case?
假设我有这样的 ADT:
sealed trait A extends Product with Serializable
object A {
case class A1() extends A
case class A2() extends A
case class A3() extends A
case class A4() extends A
}
假设我也有一个这样的 trait AFoo
:
type Foo = ...
trait AFoo { def asFoo(a: A): Foo }
现在我需要为 AFoo
提供两种不同的实现。所以我正在写这样的东西:
abstract class AFooSupport extends AFoo {
protected def asFoo1(a1: A1): Foo
protected def asFoo2(a2: A2): Foo
protected def asFoo3(a3: A3): Foo
protected def asFoo4(a4: A4): Foo
def asFoo(a: A) = a match {
case a1: A1 => asFoo1(a1)
case a2: A2 => asFoo2(a2)
case a3: A3 => asFoo3(a3)
case a4: A4 => asFoo4(a4)
}
}
class AFoo1 extends AFooSupport {
// implement asFoo1, asFoo2, asFoo3, asFoo4
}
class AFoo2 extends AFooSupport {
// implement asFoo1, asFoo2, asFoo3, asFoo4
}
这种方法可能会奏效,但我想知道是否有更好的方法。在这种情况下,您会使用 type class 吗?
乍一看,您似乎可以使用泛型作为解决方案或通过继承解决您的问题。
对于具有不同实现的具体 classes,只有一个函数 (A => Foo)
。我在这里看不到使用类型 class 的巨大优势。当其中一个参数是泛型时,我会开始考虑类型 class。
正如评论中所建议的那样,可以将模式匹配提取到折叠中
def fold[F](a: A)(f1: A1 => F, ..., f4: A4 => F): F = a match {
case a1: A1 => f1(a1)
...
}
并实现所需的功能:
def aFoo(a: A): Foo = fold(a)(afoo1, afoo2, afoo3, afoo4)
def afoo1(a: A1): Foo = ...
...
def afoo4(a: A4): Foo = ...
def bFoo(a: A): Foo = fold(a)(bfoo1, bfoo2, bfoo3, bfoo4)
...
def bfoo4(a: A4): Foo = ...
但是您的 AFooSupport
已经是一种使用继承而不是组合实现的折叠。
假设我有这样的 ADT:
sealed trait A extends Product with Serializable
object A {
case class A1() extends A
case class A2() extends A
case class A3() extends A
case class A4() extends A
}
假设我也有一个这样的 trait AFoo
:
type Foo = ...
trait AFoo { def asFoo(a: A): Foo }
现在我需要为 AFoo
提供两种不同的实现。所以我正在写这样的东西:
abstract class AFooSupport extends AFoo {
protected def asFoo1(a1: A1): Foo
protected def asFoo2(a2: A2): Foo
protected def asFoo3(a3: A3): Foo
protected def asFoo4(a4: A4): Foo
def asFoo(a: A) = a match {
case a1: A1 => asFoo1(a1)
case a2: A2 => asFoo2(a2)
case a3: A3 => asFoo3(a3)
case a4: A4 => asFoo4(a4)
}
}
class AFoo1 extends AFooSupport {
// implement asFoo1, asFoo2, asFoo3, asFoo4
}
class AFoo2 extends AFooSupport {
// implement asFoo1, asFoo2, asFoo3, asFoo4
}
这种方法可能会奏效,但我想知道是否有更好的方法。在这种情况下,您会使用 type class 吗?
乍一看,您似乎可以使用泛型作为解决方案或通过继承解决您的问题。
对于具有不同实现的具体 classes,只有一个函数 (A => Foo)
。我在这里看不到使用类型 class 的巨大优势。当其中一个参数是泛型时,我会开始考虑类型 class。
正如评论中所建议的那样,可以将模式匹配提取到折叠中
def fold[F](a: A)(f1: A1 => F, ..., f4: A4 => F): F = a match {
case a1: A1 => f1(a1)
...
}
并实现所需的功能:
def aFoo(a: A): Foo = fold(a)(afoo1, afoo2, afoo3, afoo4)
def afoo1(a: A1): Foo = ...
...
def afoo4(a: A4): Foo = ...
def bFoo(a: A): Foo = fold(a)(bfoo1, bfoo2, bfoo3, bfoo4)
...
def bfoo4(a: A4): Foo = ...
但是您的 AFooSupport
已经是一种使用继承而不是组合实现的折叠。