2016-02-15 12 views
7

Il seguente Haskell tipo di classe e istanza:Scala vs Haskell typeclasses: "catchall" istanze

class Able a where 
    able :: a -> Int 

instance Able Int where 
    able x = x 

viene comunemente tradotto a Scala in questo modo:

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

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

In Haskell ora posso definire una sorta di istanza catch-all e quindi creare un'istanza per tutti i tipi Maybe:

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

Questo definisce un istanc e di Able per Maybe Int, Maybe Bool, ecc condizione che vi sia un caso Able per Int, Bool, ecc

come si potrebbe farlo in Scala?

risposta

11

Si costruisce l'istanza da un parametro implicito per l'istanza del tipo peer A. Ad esempio:

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) 
+0

Geniale! Grazie mille :) – scravy