計算機科学のブログ

Haskell - 型によるプログラミング - Maybe型:欠損値に対処する - Maybeを使ったより複雑な計算

入門Haskellプログラミング (Will Kurt(著)、株式会社クイープ(監修、翻訳)、翔泳社)の UNIT3(型によるプログラミング)、LESSON 19(Maybe型:欠損値に対処する)、19.4(Maybeを使ったより複雑な計算)、Q19-3の解答を求めてみる。

コード

sample3.hs

main :: IO ()
main = do
    mapM_ print xs
    mapM_  (print . report) xs

data Organ = Heart | Brain | Kidney | Spleen deriving (Show, Enum)

data Container = Vat Organ | Cooler Organ | Bag Organ

instance Show Container where
  show :: Container -> String
  show (Vat organ) = mconcat [show organ, " in a vat"]
  show (Cooler organ) = mconcat [show organ, " in a cooler"]
  show (Bag organ) = mconcat [show organ, " in a bag"]

data Location = Lab | Kitchen | Bathroom deriving Show

organToContainer :: Organ -> Container
organToContainer Brain = Vat Brain
organToContainer Heart = Cooler Heart
organToContainer organ = Bag organ

placeInLocation :: Container -> (Location, Container)
placeInLocation (Vat organ) = (Lab, Vat organ)
placeInLocation (Cooler organ) = (Lab, Cooler organ)
placeInLocation (Bag organ) = (Kitchen, Bag organ)

process :: Organ -> (Location, Container)
process organ = placeInLocation (organToContainer organ)

report :: Maybe (Location, Container) -> String
report Nothing = "container not found"
report (Just (location ,container)) =
    mconcat [show container, " in the ", show location]

xs :: [Maybe (Location, Container)]
xs = map (Just . process) [Heart .. Spleen] ++ [Nothing]

入出力結果(Terminal, Zsh)

% runghc sample3.hs
Just (Lab,Heart in a cooler)
Just (Lab,Brain in a vat)
Just (Kitchen,Kidney in a bag)
Just (Kitchen,Spleen in a bag)
Nothing
"Heart in a cooler in the Lab"
"Brain in a vat in the Lab"
"Kidney in a bag in the Kitchen"
"Spleen in a bag in the Kitchen"
"container not found"
%