Haskell の文法に関しては飛ばして第8章の型や型クラスを自分で作ろう まで行こう (本を持っている人は第7章)。
data TrafficLight = Red | Yellow | Green
これを Scala で書くと:
scala> :paste
// Entering paste mode (ctrl-D to finish)
sealed trait TrafficLight
case object Red extends TrafficLight
case object Yellow extends TrafficLight
case object Green extends TrafficLight
これに Equal
のインスタンスを定義する。
scala> implicit val TrafficLightEqual: Equal[TrafficLight] = Equal.equal(_ == _)
TrafficLightEqual: scalaz.Equal[TrafficLight] = scalaz.Equal$$anon$7@2457733b
使えるかな?
scala> Red === Yellow
<console>:18: error: could not find implicit value for parameter F0: scalaz.Equal[Product with Serializable with TrafficLight]
Red === Yellow
Equal
が不変 (invariant) なサブタイプ Equal[F]
を持つせいで、Equal[TrafficLight]
が検知されないみたいだ。TrafficLight
を case class にして Red
と Yellow
が同じ型を持つようになるけど、厳密なパターンマッチングができなくなる。#ダメじゃん
scala> :paste
// Entering paste mode (ctrl-D to finish)
case class TrafficLight(name: String)
val red = TrafficLight("red")
val yellow = TrafficLight("yellow")
val green = TrafficLight("green")
implicit val TrafficLightEqual: Equal[TrafficLight] = Equal.equal(_ == _)
red === yellow
// Exiting paste mode, now interpreting.
defined class TrafficLight
red: TrafficLight = TrafficLight(red)
yellow: TrafficLight = TrafficLight(yellow)
green: TrafficLight = TrafficLight(green)
TrafficLightEqual: scalaz.Equal[TrafficLight] = scalaz.Equal$$anon$7@42988fee
res3: Boolean = false