Scala vs Haskell typeclasses: "catchall" instances

234 views Asked by At

The following Haskell type class and instance:

class Able a where
  able :: a -> Int

instance Able Int where
  able x = x

is commonly translated to Scala like so:

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

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

In Haskell I can now define a sort of catch-all instance and thereby create an instance for all Maybe types:

instance Able a => Able (Maybe a) where
  able (Just a) = able a
  able Nothing  = 0

This defines an instance of Able for Maybe Int, Maybe Bool, etc. provided that there is an instance Able for Int, Bool, etc.

How would one do that in Scala?

1

There are 1 answers

1
0__ On BEST ANSWER

You would construct the instance from an implicit parameter for the instance of the peer type A. For example:

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)