Scala

関数 ()=>AとUnit=>Aは違う

こんな関数があったとして

def foo[A](func: A => Int, param: A): Int = func(param)

以下関数をfoo関数の第一引数に渡して(第二引数はよしなに)実行してみたい。

val f: Int => Int = identity
val g: () => Int = () => 3
val h: Unit => Int = (_:Unit) => 3

実行。

foo(f, 3)   // 3が返る
foo(g, ())  // コンパイルエラー!
foo(h, ())  // 3が返る

gはコンパイルエラー。hは大丈夫。
エラーメッセージはこんな感じ。

<console>:14: error: type mismatch;
 found   : () => Int
 required: ? => Int
       foo(g, ())

ちょっと確認

改めてgの方。

scala> val g: () => Int = () => 3
g: () => Int = $$Lambda$1092/345607713@1921994e

scala> g.getClass
res1: Class[_ <: () => Int] = class $$Lambda$1092/345607713

scala> g.isInstanceOf[Function1[_,_]]
res2: Boolean = false

おお、false.
hの方。

scala> val h: Unit => Int = (_:Unit) => 3
h: Unit => Int = $$Lambda$1111/122513206@52a33c3f

scala> h.getClass
res3: Class[_ <: Unit => Int] = class $$Lambda$1111/122513206

scala> h.isInstanceOf[Function1[_,_]]
res4: Boolean = true

hはFunction1だけどgはFunction1じゃなくてFunction0でした。