Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala vs Haskell typeclasses: "catchall" instances

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?

like image 828
scravy Avatar asked Feb 15 '16 21:02

scravy


1 Answers

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)
like image 90
0__ Avatar answered Oct 14 '22 18:10

0__