関数が値を返さないかもしれないときには Maybe型を使います。
tList =[("Perl","Larry Wall"),("Ruby","Matz"),("C","Dennis Ritchie"), ("Fortran"," John Warner Backus")] mLookup :: String -> [(String,String)] -> Maybe String mLookup string ((key,dat):xs) | string == key = Just dat | otherwise = mLookup string xs mLookup _ [] = Nothing mFind :: String -> [(String,String)] -> String mFind str ls = case mLookup str ls of Just s -> "found! :" ++ s Nothing -> "not found!" > mFind "Perl" tList -- => "found! :Larry Wall" > mFind "Haskell" tList -- => "not found!"
関数が返す型を使い分けたいときは Either 型を使います。
リストを検索して見つかったときは Right 型でその値を返し、みつからないときは Left 型で照合した回数を返しています。
この照合した回数はあまり意味のある数字ではありませんが、Windows COM のinvoke 関数は実行に成功すると0x00000000、失敗すると0x00000000以外のRESULT コードを返します。で、成功したときには実効結果、失敗したときにはRESULT コードを返すようなときに重宝です。
eLookup :: String -> [(String,String)] -> Integer -> (Either Integer String) eLookup string ((key,dat):xs) n | string == key = Right dat | otherwise = eLookup string xs (n+1) eLookup _ [] n = Left n eFind :: String -> [(String,String)] -> String eFind str ls = case eLookup str ls 0 of Right s -> "found! :" ++ s Left n -> "not found : List length = " ++ show n > mFind "Ruby" tList -- => "found! :Matz" > mFind "Haskell" tList -- => "not found : List length = 5"
COM 呼び出し失敗のとき RESULT を Left で返すようにすると Left に同じ記述のあるものがいっぱい並ぶので、それを避ける withEither。
関数名 withEither は withCString, withCWString のパクリ。
withEither :: Either a b -> (b -> Either a b) -> Either a b withEither either func = case either of Left a -> Left a Right b -> func b
-- 第1引数が Left のときはそのままの値が返される。 > withEither (Left "hello") (\x->Right(100*x)) -- => Left "hello" -- 第1引数が Right のときは第1引数 の値に第2引数の関数が適用される。 > withEither (Right 123) (\x->Right(100*x)) -- => Right 12300 -- Right のとき呼ばれる関数は Left を返しても良い。 > withEither (Right 123) (\x->Left (100*x)) -- => Left 12300
Either型の値がRightかどうかチェックする関数。
Left にエラーを返すようにすれば気軽にエラーがあるかどうか確認しながらコードを書ける。
isEitherRight :: Either a b -> Bool isEitherRight either = case either of Left a -> False Right b -> True