Pixel Pedals of Tomakomai

北海道苫小牧市出身の初老の日常

Scalaの空括弧とUnit

Unit周りでハマったのでメモ。

まず、() => Any という型はあるが、()という型はない。

scala> def id(x: () => Int): () => Int = x
id: (x: () => Int)() => Int

scala> def id(x: ()): () = x
<console>:1: error: '=>' expected but ')' found.
       def id(x: ()): () = x
                   ^

Unit型の唯一の要素が()である。

scala> ().isInstanceOf[Unit]
res67: Boolean = true

() => Any は Unit => Any とは違う。

// 型が違って代入できない
scala> val emptyParentheses: () => Any = { () => 10 }
emptyParentheses: () => Any = <function0>

scala> val unit: Unit => Any = emptyParentheses
<console>:17: error: type mismatch;
 found   : () => Any
 required: Unit => Any
       val unit: Unit => Any = emptyParentheses
                               ^
// 型が違って代入できない
scala> val unit: Unit => Any = {(u: Unit) => 20}
unit: Unit => Any = <function1>

scala> val emptyParentheses: () => Any = unit
<console>:17: error: type mismatch;
 found   : Unit => Any
 required: () => Any
       val emptyParentheses: () => Any = unit
                                         ^

が、Unit => Any は空括弧で呼び出すことができる。

scala> def one(u: Unit): Int = 1
one: (u: Unit)Int

scala> one(())
res68: Int = 1

// これ、なんでエラーにならないのかわからず (Value Discardingから??)
scala> one()
res69: Int = 1

scala> one
<console>:18: error: missing arguments for method one in object $iw;
follow this method with `_' if you want to treat it as a partially applied function
              one
              ^

// これは、要請がUnit型なら{ e; () }に変換するルール(Value Discarding)より
scala> one("DUMMYYY")
res71: Int = 1

// これもValue Discarding から??
scala> one(1, "XXX", Nil)
res72: Int = 1