Haskellのforallについて理解したことを書いておく(ランクN多相限定)。 より拝借
-- コンパイル通らない
func:: ([a] -> Int) -> Int
func f = f [1, 2, 3] + f["a", "b", "c"]
-- コンパイル通る
func:: (forall a. [a] -> Int) -> Int
func f = f [1, 2, 3] + f["a", "b", "c"]
// コンパイル通る
def func(f: Seq[Any] => Int): Int = {
f(List(1, 2, 3)) + f(List("a", "b", "c"))
}
func(_.size)
// この例だと共変あるしAny型あるしでScalaではランク2多相無くても書けちゃう
// コンパイル通る
import scala.collection.mutable
def func(f: mutable.Seq[Any] => Int): Int = {
f(mutable.ListBuffer(1, 2, 3)) + f(mutable.ListBuffer("a", "b", "c"))
}
func(_.size)
// 非変にしてみるけど、ぜんぶSeq[Any]として扱えるのでやっぱ書けちゃう
// コンパイル通らない
def func[A](f: Seq[A] => Int): Int = {
f(List(1, 2, 3)) + f(List("a", "b", "c"))
}
// 無理やりHaskellの例に合わせて見る
// コンパイル通る
trait SeqConsumer {
def apply[A](seq: Seq[A]): Int
}
def func(f: SeqConsumer): Int = {
f(List(1, 2, 3)) + f(List("a", "b", "c"))
}
func(new SeqConsumer { def apply[A](seq: Seq[A]): Int = seq.size })
// trait でランク2を表現してみる