3. About Phatom Type
A phantom type is a parametrised type whose
parameters do not all appear on the right-hand
side of its definition
- Haskell wiki より抜粋 -
http://www.haskell.org/haskellwiki/Phantom_type
4. 幽霊型の例
• 型パラメータTはcase classのフィールドに使われて
いない
case class A[T](x : Int)
scala> A[String](3)
res0: A [String] = A(3)
scala> A [List[Char]](3)
res1: A [List[Char]] = A(3)
scala> res0 == res1
res2: Boolean = true
• 特にScalaの場合、Type Erasureにより実⾏行行時に型パ
ラメータは消える
18. 2つの型パラメータをとる型の
シンタックスシュガー
scala> class Op[A, B] ()
scala> val x: Op[Int, String] = new Op
x: Op[Int,String] = Op@ab612f8
scala> val x: Int Op String = new Op
x: Op[Int,String] = Op@165e6c89
• 中置記法の⽅方が型の演算⼦子っぽく⾒見見える
• クラス名に記号も使える。記号の⽅方がより演算⼦子っぽい
19. Scala 2.10-M7の実装
sealed abstract class =:=[From, To]
extends (From => To) with Serializable
private[this] final val singleton_=:= =
new =:=[Any,Any] { def apply(x: Any): Any = x }
object =:= {
implicit def tpEquals[A]: A =:= A =
singleton_=:=.asInstanceOf[A =:= A]
}
• From => To を継承しているため、型を変換する関数とし
て使える
def func[A](x1: A)(implicit w: A =:= B ) = {
val x2 = w(x1) // x2はB型として使える
...
}
• Serializableを継承している利⽤用は不明
20. generalized type constraints
scala> implicitly[Int =:= Int]
res7: =:=[Int,Int] = <function1>
scala> implicitly[Int =:= String]
<console>:9: error: Cannot prove that Int =:= String.
implicitly[Int =:= String]
^
• 異なる型を渡すとコンパイルエラー
28. <%< はなくなった
(2.10から)
• 「A => B」でOK
scala> implicitly[ Int <%< Long ]
<console>:12: error: not found: type >%>
implicitly[ Int <%< Long ]
^
scala> implicitly[ Int => Long ]
res5: Int => Long = <function1>
29. <%<は、なぜなくなったのか
• SI-2781
• type inference constraints should be
carried along during search for chained
implicits
• https://issues.scala-lang.org/browse/
SI-2781
30. 演習問題
1
• 9ページの例をコンパイルエラーを出すようにする
scala> Dinner.start.cookSalad.cookCake.serve()
<console>:8: error: Cannot prove that Dinner.Empty =:=
Dinner.Ready.
Dinner.start.cookSalad.cookCake.serve()
^
scala> Dinner.start.cookSalad.cookCake.cookSalad
<console>:8: error: Cannot prove that Dinner.Ready =:=
Dinner.Empty.
Dinner.start.cookSalad.cookCake.cookSalad
^
scala> Dinner.start.cookSalad.cookCake.cookSteak.serve()
Now you can eat!
31. 演習問題 2
• AがBの⼦子クラスであるかをチェックする型を考えてみる
scala> trait A
scala> trait B with A
scala> implicitly[ B <:< A ]
res9: <:<[B,A] = <function1>
scala> implicitly[ A <:< B ]
<console>:14: error: Cannot prove that A <:< B.
implicitly[ A <:< B ]
32. 参考文献
• Type classes as objects and implicitsBruno
C.d.S. Oliveira, Adriaan Moors,
Martin Odersky
OOPSLA ʻ‘10 Proceedings of the ACM
international conference on Object oriented
programming systems languages and
applications, 2010
この論⽂文の「6.6 Encoding generalized
constraints」に>:>の話がある(少しだけど)