計算機科学のブログ

コンテキストでの型の操作 Applicative型クラス:関数をコンテキスト内で使用する Map型、lookup関数、Maybe、<$>と<*>

入門Haskellプログラミング (Will Kurt(著)、株式会社クイープ(監修、翻訳)、翔泳社)のUNIT5(コンテキストでの型の操作)、LESSON28(Applicative型クラス:関数をコンテキスト内で使用する)、28.5(練習問題)Q28-3の解答を求めてみる。

コード

import qualified Data.Map as Map

data RobotPart = RobotPart
  { name :: String,
    description :: String,
    cost :: Double,
    count :: Int
  }
  deriving (Show)

leftArm :: RobotPart
leftArm =
  RobotPart
    { name = "left arm",
      description = "left arm for face punching!",
      cost = 1000.00,
      count = 3
    }

rightArm :: RobotPart
rightArm =
  RobotPart
    { name = "right arm",
      description = "right arm for kind hand gestures",
      cost = 1025.00,
      count = 5
    }

robotHead :: RobotPart
robotHead =
  RobotPart
    { name = "robot head",
      description = "this head looks mad",
      cost = 5092.25,
      count = 2
    }

partsDB :: Map.Map Int RobotPart
partsDB =
  let keys = [1 .. 3]
      vals = [leftArm, rightArm, robotHead]
      keyVals = zip keys vals
   in Map.fromList keyVals

main :: IO ()
main = do
  idStr1 <- getLine
  idStr2 <- getLine
  let id1 = read idStr1
  let id2 = read idStr2
  let partMaybe1 = Map.lookup id1 partsDB
  let partMaybe2 = Map.lookup id2 partsDB
  let costMaybe1 = cost <$> partMaybe1
  let costMaybe2 = cost <$> partMaybe2
  let costMaybe = min <$> costMaybe1 <*> costMaybe2
  if costMaybe == costMaybe1
    then print partMaybe1
    else print partMaybe2

入出力結果(Terminal, Zsh)

% runghc sample3.hs
1
2
Just (RobotPart {name = "left arm", description = "left arm for face punching!", cost = 1000.0, count = 3})
kamimura@MacBook lesson28 % runghc sample3.hs
1
3
Just (RobotPart {name = "left arm", description = "left arm for face punching!", cost = 1000.0, count = 3})
kamimura@MacBook lesson28 % runghc sample3.hs
2
3
Just (RobotPart {name = "right arm", description = "right arm for kind hand gestures", cost = 1025.0, count = 5})
kamimura@MacBook lesson28 % runghc sample3.hs
1
4
Nothing
%