🐡
Scala3(Dotty)でenumで自然数を定義してみる
Scala3がリリースされました! Bookの例にあった、enumの例で少し遊んでみました。
Scala3-Book DOMAIN MODELINGのenum
これがenumのシンプルな例です。
enum CrustSize:
case Small, Medium, Large
import CrustSize.*
val currentCrustSize = Small
// enums in a `match` expression
currentCrustSize match
case Small => println("Small crust size")
case Medium => println("Medium crust size")
case Large => println("Large crust size")
// enums in an `if` statement
if currentCrustSize == Small then println("Small crust size")
代数的データ型らしい使い方として、自然数をenumで定義してみた例です。
enum Nat:
case Zero
case Succ(pred: Nat)
これだけではつまらないので、このNat
を使って足し算を定義してみましょう。左項のpred(前の値)と右項を足したもののSuccは左項 + 右項
に等しいです。
def plus(left: Nat, right: Nat): Nat =
(left, right) match
case (Zero, r) => r
case (l, Zero) => l
case (Succ(pl), r) => Succ(plus(pl, r))
もっとシンプルに左項のパターンマッチだけでも定義できます。
def plus(left: Nat, right: Nat): Nat =
left match
case Zero => right
case Succ(pl) => Succ(plus(pl, right))
それでは自然数をいくつか用意して、足し算ができているか確かめてみましょう。@main
アノテーションでmainメソッド手軽に定義できるのもScala3のいいところですね。enum NatのZero
やSucc
などのcaseを参照する場合は、import Nat.*
とすることで可能です。import Nat._
と書いても動きますが、Bookやドキュメントは*を使っているので、そのほうがお行儀が良さそうです。
import Nat.*
val one = Succ(Zero)
val two = Succ(one)
val three = Succ(two)
@main def main: Unit =
println(three) // Succ(Succ(Succ(Zero)))
println(plus(one, two) == three) // true
せっかくなのでElmでも書かせてください。これであなたは、ElmもScala3もマスター!
type Nat
= Zero
| Succ Nat
plus : Nat -> Nat -> Nat
plus left right =
case ( left, right ) of
( Zero, r ) ->
r
( l, Zero ) ->
l
( Succ pl, r ) ->
Succ <| plus pl r
Discussion