ラムダ関数にガードを付けることは可能ですか?
例えば:
\k
| k < 0 -> "negative"
| k == 0 -> "zero"
| otherwise -> "positive"
他の回答は、この回答が最初に書かれてから導入された拡張機能LambdaCase
およびMultiWayIf
がこれをどのように解決できるかを示しています。それらがなければ、最も近い直接翻訳は少し似ています
\k -> case () of
_ | k < 0 -> "negative"
| k == 0 -> "zero"
| otherwise -> "positive"
GHC 7.6.1 以降では、MultiWayIf
という拡張機能があり、次のように記述できます。
\k -> if
| k < 0 -> "negative"
| k == 0 -> "zero"
| otherwise -> "positive"
少なくとも、case
を使用する代替方法よりも、どちらを見るのが楽しいでしょう。
パターンマッチングには、LambdaCase
と呼ばれる関連する拡張機能があります。
\case
"negative" -> -1
"zero" -> 0
"positive" -> 1
_ -> error "invalid sign"
ただし、これらの拡張機能は標準のHaskellの一部ではないため、ファイルの上部にある{-# LANGUAGE LambdaCase #-}
または{-# LANGUAGE MultiWayIf #-}
プラグマを介して明示的に有効にするか、フラグ-XLambdaCase
を使用してコンパイルするか、 -XMultiWayIf
。
読者の視覚的な流れを壊さないように、ラムダを短くて甘く保つのが好きです。定義が構文的にかさばり、ガードを保証するのに十分な関数の場合、それをwhere
句に貼り付けてみませんか?
showSign k = mysign ++ " (" ++ show k ++ ")"
where
mysign
| k < 0 = "negative"
| k == 0 = "zero"
| otherwise = "positive"
LambdaCaseでそれを行うためのエレガントで簡潔な方法:
{-# LANGUAGE LambdaCase #-}
\case k | k < 0 -> "negative"
| k == 0 -> "zero"
| otherwise -> "positive"
または
\case
k | k < 0 -> "negative"
| k == 0 -> "zero"
| otherwise -> "positive"
EOFエラーをキャッチするために使用した場合:
{-# LANGUAGE ScopedTypeVariables #-}
o <- hGetContents e `catch` (\case (e :: IOException) | isEOFError e -> return "")
さらに別の方法では、LambdaCase
とViewPatterns
GHC拡張機能の組み合わせを使用します。
{-# LANGUAGE LambdaCase, ViewPatterns #-}
\case
((< 0) -> True) -> "negative"
((==0) -> True) -> "zero"
_ -> "positive"
これにより、中間変数に名前を付ける必要がなくなります。