Scala与Haskell的类型类: "catchall"实例

8
以下是Haskell的类型类和实例:
class Able a where
  able :: a -> Int

instance Able Int where
  able x = x

通常将其翻译为Scala,如下所示:

trait Able[A] {
  def able(a: A): Int
}

implicit object AbleInt extends Able[Int] {
  def able(a: Int) = a
}

在 Haskell 中,我现在可以定义一种类似于 catch-all 实例的东西,从而为所有 Maybe 类型创建一个实例:
instance Able a => Able (Maybe a) where
  able (Just a) = able a
  able Nothing  = 0

这定义了一个针对 Maybe IntMaybe Bool等实例的 Able,前提是已经存在 IntBool等类型的 Able 实例。

那么在 Scala 中该如何实现呢?

1个回答

12

你需要使用同级类型 A 的隐式参数来构造实例。例如:

implicit def AbleOption[A](implicit peer: Able[A]) = new Able[Option[A]] {
  def able(a: Option[A]) = a match {
    case Some(x) => peer.able(x)
    case None    => 0
  }
}

assert(implicitly[Able[Option[Int]]].able(None)    == 0)
assert(implicitly[Able[Option[Int]]].able(Some(3)) == 3)

巧妙!非常感谢 :) - scravy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接