What is Type Class Type - litelally Class - a group by reason of common characteris7c Type != Class Type Class == Class of Types Be aware of the seman.cs of the Class and Type here is based on Haskell but Scala
What for Type Class For ad hoc polymorphism def sum[A](xs: List[A]): A = ??? // A should be Int / String sum(List("a", "bc", "de")) // => "abcde" sum(List(1, 2, 3)) // => 6 sum(List(true, false)) // Kaboom! Can't compile Polymorphic behavior by instance type def sum[A](xs: List[A]): A = if (xs.isEmpty) A.unit else A.add(xs.head, sum(xs.tail)) Can it be done?
In Haskell class MyMonoid a where add :: a -> a -> a instance MyMonoid Int where add x y = x + y instance MyMonoid Double where add x y = x + y mySum :: (MyMonoid a) => a -> a -> a mySum x y = add x y main = do print $ mySum (1::Int) (2::Int) -- 3 print $ mySum (1::Double) (2::Double) -- 3.0 print $ mySum True False -- Kaboom! Can't compile
The nature of Type class • Type already defined • Constrain receivable type set by interface • Interface implemented independently the type but associated with the type • Type resolu9on in compile 9me
Life without Type Class - 11 Some standard classes for SemiGroup and Monoid abstract class SemiGroup[A] { def add(x: A, y: A): A } abstract class Monoid[A] extends SemiGroup[A] { def unit: A } 1 h$p:/ /lampwww.epfl.ch/~odersky/talks/wg2.8-boston06.pdf
Life without Type Class - 21 Two implementa-ons of monoids object stringMonoid extends Monoid[String] { def add(x : String, y : String): String = x.concat(y) def unit : String = "" } object intMonoid extends Monoid[int] { def add(x : Int, y : Int): Int = x + y def unit: Int = 0 } 1 h$p:/ /lampwww.epfl.ch/~odersky/talks/wg2.8-boston06.pdf
Life without Type Class - 31 A sum method which works over arbitrary monoids def sum[A](xs : List[A])(m : Monoid[A]): A = if (xs.isEmpty) m.unit else m.add(xs.head, sum(xs.tail)(m)) One invokes this sum method by code such as sum(List("a", "bc", "de"))(stringMonoid) // => "abcde" sum(List(1, 2, 3))(intMonoid) // => 6 sum(List(true, false))(intMonoid) // => Can't compile definitely 1 h$p:/ /lampwww.epfl.ch/~odersky/talks/wg2.8-boston06.pdf
vs. Haskell Haskell <-> Scala type class <-> trait / abstract class instance <-> inplicit object context / type class constraint <-> implicit parameter
Haskell code revisited class MyMonoid a where add :: a -> a -> a instance MyMonoid Int where add x y = x + y instance MyMonoid Double where add x y = x + y mySum :: (MyMonoid a) => a -> a -> a mySum x y = add x y main = do print $ mySum (1::Int) (2::Int) -- 3 print $ mySum (1::Double) (2::Double) -- 3.0 print $ mySum True False -- Kaboom! Can't compile
Conclusion The beauty of type class and implicit • Type (Interface) with implementa5on at external of the type which is already exists • Sta)c Type Safe • Implicit parameter / defini5on binds to Type / Implement Not for laziness