Either モナドの使い方
Either a b
Either a b 型は a と b という2種類のデータ型を保持できる。つまり、Either 型のデータコンストラクタは Left a と Right b である。データコンストラクタ Left と Right は a と b という異なる型のデータをコンテナに保持できる。Either 型は Maybe 型と同じように失敗する可能性のある処理の値として使う。Right b は Just b と同じ意味がある。Left "error" は Nothing と同じ働きをするが、フィールドにエラーメッセージを入れることができる。Right は正しいという意味と、Either a b の右側にあるという意味が掛けてある。
Either 型が値の関数
Either a b 型が値になる関数の例を次に示す。
Prelude> :{ Prelude| foo :: Int -> Either String Int Prelude| foo x Prelude| | x > 5 = Right x Prelude| | otherwise = Left "error" Prelude| :} Prelude> foo 3 Left "error" Prelude> foo 6 Right 6
Either モナド
Maybe 型と同じように Either 型はモナドであるので、do 記法の中でプログラムされたり、return 関数や <- 記法を使うことができる。
Prelude> do return 3 :: Either String Int Right 3 Prelude> do x <- return 3; Left "short cut!!"; return x :: Either String Int Left "short cut!!"
do 記法のブロックのどの段階にでも Left a が現れると、ショートカットが行われその後の処理は行われない。これは Maybe モナドの Nothing に似ているが、Either の場合は Left a で例外やエラーメッセージを保持できる。
Either 型を引数にする関数
Data.Either には Either 型を取り扱う関数が定義されている。
Prelude> :browse Data.Either data Either a b = Left a | Right b either :: (a -> c) -> (b -> c) -> Either a b -> c Data.Either.isLeft :: Either a b -> Bool Data.Either.isRight :: Either a b -> Bool Data.Either.lefts :: [Either a b] -> [a] Data.Either.partitionEithers :: [Either a b] -> ([a], [b]) Data.Either.rights :: [Either a b] -> [b]
上の関数のうち either 関数の型は次のようになる。
Prelude> :t either either :: (a -> c) -> (b -> c) -> Either a b -> c
either 関数の第1引数は a 型のデータを引数とする関数であり、第2引数は b 型のデータを引数とする関数である。ただし、a 型と b 型の関数の戻り値は同じ型 c でなければならない。第3引数は Either a b 型のデータである。
either は第3の引数が Left a のときはフィールドの a に第1引数の関数を適用し、Right b のときは第2引数の関数を適用する。これによって、Left a の場合と Right b の場合の処理を使い分けることができる。
Prelude> s = Left "foo" :: Either String Int Prelude> n = Right 3 :: Either String Int Prelude> either length (*2) s 3 Prelude> either length (*2) n 6
Either 型はパーサのような処理が失敗するかもしれないプログラムに活用されている。