2026-09-19
LookupChain.hs
lookupChain :: [(String, String)] -> [(String, Int)] -> String -> Maybe Int
lookupChain step1 step2 key = lookup key step1 >>= \mid_ -> lookup mid_ step2
main :: IO ()
main = do
let names = [("alice", "id1"), ("bob", "id2")]
scores = [("id1", 90), ("id3", 70)]
print (lookupChain names scores "alice")
print (lookupChain names scores "bob")
print (lookupChain names scores "carol")
lookupChainは、途中で見つからなかった場合に-1のような番兵値を返す代わりにMaybe Intを使っています。mainは何を出力するでしょうか?(3行)
Answer
Just 90、Nothing、Nothing — 1行ずつ。"alice"はnamesで"id1"に見つかり、続けてscoresで"id1"を引くとJust 90になります。"bob"はnamesでは"id2"に見つかりますが、scoresには"id2"が無いので2段目のlookupがNothingを返します。"carol"はnamesの時点で見つからずNothingになり、Maybeの>>=は左側がNothingだと右側の関数を一切呼ばずにNothingを返す(短絡する)ので、2段目のlookupは実行されません。もしIntだけで書いて「見つからなければ-1」という番兵値にしていたら、各段で-1かどうかを自分で確認しなければならず、確認を1箇所でも忘れると見つからなかったはずの値が次の段にそのまま渡ってしまいます。Maybeという専用の型を使うことで、「まだ値がない」状態が型として表現され、>>=がその伝播を代わりに面倒みてくれます。