Maybe型は、Elm言語で「値があるかもしれないし、ないかもしれない」という状況を扱うための型です。そのため、Elmの多くの基本的な関数の型シグネチャーに登場し、これを理解することはとても重要です。Maybe型は次のように定義されています。
type Maybe a = Nothing | Just a
これはElmの用語で「カスタム型」の定義と呼ばれます。この型の値は、Nothingであるか、型aの何かを持つJustであるかのどちらかである、ということを示しています。Maybeの値を作るには、2つのコンストラクターNothingとJustのどちらかを使います。Maybeの中身を取り出すには、パターンマッチングを使います。
matthieu : Maybe String
matthieu = Just "Matthieu"
anon : Maybe String
anon = Nothing
sayHello : Maybe String -> String
sayHello maybeName =
case maybeName of
Nothing -> "Hello, World!"
Just someName -> "Hello, " ++ someName ++ "!"
sayHello matthieu
--> "Hello, Matthieu!"
sayHello anon
--> "Hello, World!"
また、Maybe型を操作するための便利な関数が、Maybeモジュールにいくつも用意されています。
sayHelloAgain : Maybe String -> String
sayHelloAgain name = "Hello, " ++ Maybe.withDefault "World" name ++ "!"
capitalizeName : Maybe String -> Maybe String
capitalizeName name = Maybe.map String.toUpper name
capitalizeName matthieu
--> Just "MATTHIEU"
capitalizeName anon
--> Nothing
この演習では、ロールプレイングゲームの仕組みを実装します。 プレイヤーのキャラクターは、次の型で表されます。
type alias Player =
{ name : Maybe String
, level : Int
, health : Int
, mana : Maybe Int
}
このゲームのプレイヤーは、レベル10に達しないとマナプールを解放できず、呪文を唱えられません。 ここでは、このゲームの2つの機能、蘇生の仕組みと呪文詠唱の仕組みに取り組みます。
introduce関数の中身を書きましょう。
身を潜めているプレイヤーは名前を隠していることがあり、その場合は"Mighty Magician"として紹介されます。
それ以外の場合は、自分の名前をそのまま使って自己紹介します。
introduce { name = Nothing, level = 2, health = 8, mana = Nothing }
--> "Mighty Magician"
introduce { name = Just "Merlin", level = 2, health = 8, mana = Nothing }
--> "Merlin"
revive関数は、プレイヤーのキャラクターが本当に死んでいるか(体力が0になっているか)を確認します。
死んでいる場合は、体力が100の新しいPlayerインスタンスを返します。
そうでなければ、つまりプレイヤーのキャラクターが死んでいない場合は、revive関数はNothingを返します。
プレイヤーのレベルが10以上の場合、マナ100でも蘇生されます。
プレイヤーのレベルが10未満の場合、マナはNothingになります。
revive関数は、プレイヤーのレベルを保つ必要があります。
deadPlayer = { name = Nothing, level = 2, health = 0, mana = Nothing }
revive deadPlayer
--> Just { name = Nothing, level = 2, health = 100, mana = Nothing }
体力が1以上のプレイヤーに対してreviveメソッドが呼び出された場合、関数はNothingを返す必要があります。
alivePlayer = { name = Nothing, level = 2, health = 42, mana = Nothing }
revive alivePlayer
--> Nothing
castSpell関数は、呪文にかかるマナの量を表すIntと、Playerを引数に取ります。
更新されたプレイヤーと、唱えた呪文が与えるダメージ量を返します。
呪文の詠唱に成功すると、その呪文のマナコストの2倍のダメージを与えます。
ただし、プレイヤーのマナが足りない場合は、何も起こらず、プレイヤーは変化せず、ダメージも発生しません。
プレイヤーがマナプールすら持っていない場合、呪文を唱えようとすると、体力がその呪文のマナコスト分だけ減り、ダメージは与えません。
wizard = { name = Nothing, level = 18, health = 123, mana = Just 30 }
( updatedWizard, damage ) = castSpell 14 wizard
updatedWizard.mana --> Just 16
damage --> 28