Biacco42
February 26, 2017
800

# Poor man's type classes revisited

Odersky 博士の発表資料 "Poor man's type class" を読んで、Scala における型クラスと implicit について簡単にまとめました

## Biacco42

February 26, 2017

## Transcript

1. Poor man's type classes
revisited
@Biacco42

2. At ﬁrst,
what is Type Class

3. 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

4. What for Type Class
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
Can it be done?

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

6. The nature of Type class
• Constrain receivable type set by interface
• Interface implemented independently the type
but associated with the type
• Type resolu9on in compile 9me

7. 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.epﬂ.ch/~odersky/talks/wg2.8-boston06.pdf

8. 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.epﬂ.ch/~odersky/talks/wg2.8-boston06.pdf

9. 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
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.epﬂ.ch/~odersky/talks/wg2.8-boston06.pdf

10. Type safe but duplica0on
sum(List("a", "bc", "de"))(stringMonoid) // => "abcde"
sum(List("a", "bc", "de")) // Want to be

11. Implicits

12. Implicit parameter
Implicitly inser.ng value by Type

13. Implicit parameter
Implicitly inser.ng value by Type
def sum[A](xs : List[A])(implicit m : Monoid[A]): A =
if (xs.isEmpty) m.unit
implicit object stringMonoid extends Monoid[String] {
def add(x : String, y : String): String = x.concat(y)
def unit : String = ""
}
implicit object intMonoid extends Monoid[Int] {
def add(x : Int, y : Int): Int = x + y
def unit: Int = 0
}

14. Implicit parameter
Implicitly inser.ng value by Type
sum(List(1, 2, 3))
Looks like wanted form! Equals to
sum(List(1, 2, 3))(intMonoid)

type class <-> trait / abstract class
instance <-> inplicit object
context / type class constraint <-> implicit parameter

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

17. Trans Scala code
trait MyMonoid[A] {
def add(x: A, y: A): A
def unit: A
}
implicit object intMonoid extends MyMonoid[Int] {
def add(x : Int, y : Int): Int = x + y
def unit: Int = 0
}
implicit object doubleMonoid extends MyMonoid[Double] {
def add(x : Double, y : Double): Double = x + y
def unit: Double = 0
}
def mySum[A](x: A, y: A)(implicit m : MyMonoid[A]): A = m.add(x, y)
mySum(1, 2) // => 3
mySum(1.0, 2.0) // => 3.0
mysum(true, false) // Compile error

18. 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 / deﬁni5on binds to Type / Implement
Not for laziness