top page > computer > haskell > web_lecture > for_programmer > guard0.html
更新日:
文責: 重城良国

ガード

はじめに

パターンマッチではなく条件によって処理をわけたい。0だけを特別扱いするにはパターンマッチで良い。0未満と0以上で処理をわけるにはパターンマッチは直接は使えない。

0未満を考慮した平方根

0未満ではNothingを返す関数sqrt'を考える。

今まで学んできた範囲内で

sqrt0.hs

sqrt' x = sqrtBool (x < 0) x

sqrtBool True _ = Nothing
sqrtBool _ x = Just (sqrt x)

補助関数sqrtBoolでTrue, Falseにマッチさせる。

ガードを使う

Bool値に対するパターンマッチは頻出なので略記法がある。

sqrt1.hs

sqrt' x
| x < 0 = Nothing
| otherwise = Just (sqrt x)

構文

[関数名] [引数1] [引数2] ...
| [Bool値を返す式1] = [結果の式1]
| [Bool値を返す式2] = [結果の式2]
...
| otherwise = [結果の式n]

「Bool値を返す式」がガードだ。ガードがFalseなら次のガードへ進む。Trueなら対応する「結果の式」が返される。変数otherwiseは変数piのように定義ずみの変数でありTrueに束縛されている。読みやすさのために定義されている。直接Trueと書いても同じだ。

レイアウトルールをすこし

{}でかこったり';'でくぎったりせずにレイアウトで構造を表現できる。同じレベルの兄弟要素の列挙はインデントをそろえる。タブは8タブだ。関数定義同士は兄弟要素だ。ふつうはインデント0でそろえる。

[レイアウトルールの図]

1行が長くなるときやわかりやすさのために複数行にわけるときはインデントを深くして続きであることを示す。

some n = n * 1234567890 + 9876543210
	* 789345123

* 789345123の行は関数定義の行よりインデントが深いので関数someの定義の続きとなる。インデントがないと* 789345123が新たな定義のはじまりと解釈されエラーとなる。

ガードには改行は不要だ。

sqrt' x | x < 0 = Nothing | otherwise = Just (sqrt x)

たいていは見やすさのために複数行にわける。ガードは関数定義の続きなので関数定義の1行目より深くインデントする。

まとめ

True, Falseに対するパターンマッチは頻出なのでガードという略記法がある。ガードは関数定義に複数つけられる。

| [Bool値を返す式] = [結果となる式]

課題

  1. 3の倍数なら3で割りそれ以外はそのままにする関数div3を定義せよ

「パターンマッチ」へもどる 「型とは何か」へ

正当なCSSです! HTML5 Powered with CSS3 / styling, and Semantics