Option型Option型は、値が存在する場合と存在しない場合を表すために使われます。
これはgleam/optionモジュールで次のように定義されています。
type Option(a) {
Some(a)
None
}
Someコンストラクターは、値が存在するときにその値を包むために使われ、Noneコンストラクターは、値が存在しないことを表すために使われます。
Optionの中身にアクセスするには、パターンマッチングを使うことが多いです。
import gleam/option.{type Option, None, Some}
pub fn say_hello(person: Option(String)) -> String {
case person {
Some(name) -> "Hello, " <> name <> "!"
None -> "Hello, Friend!"
}
}
say_hello(Some("Matthieu"))
// -> "Hello, Matthieu!"
say_hello(None)
// -> "Hello, Friend!"
gleam/optionモジュールには、Option型を扱うための便利な関数もいくつか定義されています。たとえばunwrapは、Optionの中身を返しますが、それがNoneの場合はデフォルト値を返します。
import gleam/option.{type Option}
pub fn say_hello_again(person: Option(String)) -> String {
let name = option.unwrap(person, "Friend")
"Hello, " <> name <> "!"
}
ジョシュは新しいロールプレイングゲームを制作中で、いくつかの仕組みの実装に助けが必要です。
introduce関数を実装しましょう。
ステルス状態のプレイヤーは名前を隠していることがあり、その場合は"Mighty Magician"として紹介されます。
それ以外の場合は、プレイヤーの名前を使って紹介します。
introduce(Player(name: None, level: 2, health: 8, mana: None))
// -> "Mighty Magician"
introduce(Player(name: Some("Merlin"), level: 2, health: 8, mana: None))
// -> "Merlin"
revive関数は、プレイヤーのキャラクターが本当に死んでいるか(体力が0になっているか)を確認します。
死んでいる場合は、体力100の新しいPlayerインスタンスを返します。
そうでない場合、プレイヤーのキャラクターが死んでいなければ、revive関数はNoneを返します。
プレイヤーのレベルが10以上なら、マナも100にして復活させます。
プレイヤーのレベルが10未満なら、マナはそのままにします。
revive関数はプレイヤーのレベルを保持します。
let dead_player = Player(name: None, level: 2, health: 0, mana: None)
revive(dead_player)
// -> Some(Player(name: None, level: 2, health: 100, mana: None))
体力が1以上あるプレイヤーに対してreviveメソッドを呼び出すと、この関数はNoneを返します。
let alive_player = Player(name: None, level: 2, health: 42, mana: None)
revive(alive_player)
// -> None
cast_spell関数は、呪文に必要なマナの量を表すIntと、Playerを引数に取ります。
更新されたプレイヤーと、唱えた呪文が与えるダメージ量を返します。
呪文の詠唱に成功すると、呪文のマナコストの2倍のダメージを与えます。
ただし、プレイヤーのマナが足りない場合は何も起こらず、プレイヤーは変化せず、ダメージも与えられません。
プレイヤーにマナプールすらない場合、呪文を唱えようとすると、呪文のマナコスト分だけ体力が減り、ダメージは与えられません。
プレイヤーの体力は0未満にはならないことに注意してください。
let wizard = Player(name: None, level: 18, health: 123, mana: Some(30))
let #(wizard, damage) = cast_spell(wizard, 14)
wizard.mana // -> Some 16
damage // -> 28