こわくない型クラス	
 
@kmizu	
 
Scala	
 Conference	
 in	
 Japan	
 2013	
 座長	
 
Scalaエヴァンジェリスト(に戻った?)
こわくない話
型クラスは怖くない	
 
型クラスは友達
本当に?
本当です(真顔)
簡単な例題
リストの要素を全て足し合わせた値を返
す関数
素直な解
def	
 sum(list:	
 List[Int]):	
 Int	
 =	
 
list.foldLeft(0)(_	
 +	
 _)
これでOK?
Intにしか適用できない
加算できる型ならなんでもsumしたい	
 
(Int,Long,Float,Doubleとか)
trait	
 Monoid[A]	
 {	
 
	
 	
 def	
 plus(x:	
 A,	
 y:	
 A):	
 A	
 
	
 	
 def	
 zero:	
 A	
 
}	
 
	
 
def	
 sum[A](list:	
 List[A])(m:	
 Monoid[A]):	
 A	
 =	
 {	
 
	
 	
 list.foldLeft(m.zero)	
 {	
 case	
 (total,	
 e)	
 =>	
 
	
 	
 	
 	
 m.plus(total,	
 e)	
 
	
 	
 }	
 
}
ここまでが準備
object	
 IntMonoid	
 extends	
 Monoid[Int]	
 {	
 
	
 	
 def	
 plus(x:	
 Int,	
 y:	
 Int):	
 Int	
 =	
 x	
 +	
 y	
 
	
 	
 def	
 zero:	
 Int	
 =	
 0	
 
}	
 
	
 
sum(List(1,	
 2,	
 3,	
 4))(IntMonoid)
object	
 DoubleMonoid	
 extends	
 Monoid[Double]	
 {	
 
	
 	
 def	
 plus(x:	
 Double,	
 y:	
 Double):	
 Double=	
 x	
 +	
 y	
 
	
 	
 def	
 zero:	
 Double	
 =	
 0.0	
 
}	
 
	
 
sum(List(1.0,	
 2.0,	
 3.0,	
 4.0))(DoubleMonoid)
やった!
毎回	
 XXXMonoid渡すの?
めんどくさい
その気持ちをわかって欲しい
気持ちを伝える方法
trait	
 Monoid[A]	
 {	
 
	
 	
 def	
 plus(x:	
 A,	
 y:	
 A):	
 A	
 
	
 	
 def	
 zero:	
 A	
 
}	
 
def	
 sum[A](list:	
 List[A])(	
 
	
 	
 implicit	
 m:	
 Monoid[A]):	
 A	
 =	
 {	
 
	
 	
 list.foldLeft(m.zero)	
 {	
 case	
 (total,	
 e)	
 =>	
 
	
 	
 	
 	
 m.plus(total,	
 e)	
 
	
 	
 }	
 
}
implicit	
 object	
 DoubleMonoid	
 extends	
 
Monoid[Double]	
 {	
 
	
 	
 def	
 plus(x:	
 Double,	
 y:	
 Double):	
 Double=	
 x	
 +	
 y	
 
	
 	
 def	
 zero:	
 Double	
 =	
 0.0	
 
}	
 
	
 
implicit	
 object	
 IntMonoid	
 extends	
 
Monoid[Int]	
 {	
 
	
 	
 def	
 plus(x:	
 Int,	
 y:	
 Int):	
 Int	
 =	
 x	
 +	
 y	
 
	
 	
 def	
 zero:	
 Double	
 =	
 0
sum(List(1,	
 2,	
 3,	
 4,	
 5))	
 //	
 ⇒	
 15	
 
sum(List(1.0,	
 2.0,	
 3.0.	
 4.0,	
 5.0))	
 //	
 ⇒	
 15.0
他の型のListもsumしたくなったら?
implicit	
 object	
 BooleanMonoid	
 extends	
 
Monoid[Boolean]	
 {	
 
	
 	
 def	
 plus(x:	
 Boolean,	
 y:	
 Boolean):	
 Boolean	
 =	
 	
 
	
 	
 	
 	
 x	
 |	
 y	
 
	
 	
 def	
 zero:	
 Boolean	
 =	
 false	
 
}	
 
	
 
List(true,	
 false,	
 true)	
 //	
 ⇒	
 true	
 
List(false,	
 false,	
 false)	
 //	
 ⇒	
 true
話を戻します
めんどくさい	
 
	
 
def	
 sum[A](list:	
 List[A])(	
 
	
 	
 implicit	
 m:	
 Monoid[A]):	
 A	
 =	
 {	
 
	
 	
 list.foldLeft(m.zero)	
 {	
 case	
 (total,	
 e)	
 =>	
 
	
 	
 	
 	
 m.plus(total,	
 e)	
 
	
 	
 }	
 
}
def	
 sum[A:Monoid](list:	
 List[A]):	
 A	
 =	
 {	
 
	
 	
 list.foldLeft(m.zero)	
 {	
 case	
 (total,	
 e)	
 =>	
 
	
 	
 	
 	
 m.plus(total,	
 e)	
 
	
 	
 }	
 
}
型クラスという言葉	
 
出てきましたか?
Monoid[A]	
 みたいなのをScalaで	
 
型クラスと呼んでいるだけ	
 
厳密には説明の順番が逆だけどそこは気にしない
Haskellの型クラスも	
 
原理は同じ
Scalaでは	
 
少し中身が見えている
むしろわかりやすい
詳しく知りたい人向けの参考文献	
 
	
 
	
 
Martin	
 Odersky,	
 Poor	
 Man's	
 Type	
 Classes,	
 2006	
 
http://lampwww.epfl.ch/~odersky/talks/wg2.8boston06.pdf

こわくない型クラス