計算機科学のブログ

コンテキストでの型の操作 do表記を使ってMonadを扱いやすくする Maybe、一般化

入門Haskellプログラミング (Will Kurt(著)、株式会社クイープ(監修、翻訳)、翔泳社)のUNIT5(コンテキストでの型の操作)、LESSON 31(do表記を使ってMonadを扱いやすくする)、31.4(練習問題)Q31-3の解答を求めてみる。

コード

lesson/app/Main.hs

module Main (main) where

import Lib
  ( comparePizzas,
    describePizza,
  )

sizeData :: [Double]
sizeData = [2, 3]

costData :: [Double]
costData = [9, 10]

maybeMain :: Monad m => m Double -> m Double -> m String
maybeMain size cost = do
  size1 <- size
  cost1 <- cost
  size2 <- size
  cost2 <- cost
  return $
    describePizza $
      comparePizzas
        (size1, cost1)
        (size2, cost2)

main :: IO ()
main = do
  mapM_ print $ maybeMain sizeData costData

lesson/src/Lib.hs

module Lib
  ( describePizza,
    comparePizzas,
  )
where

type Pizza = (Double, Double)

costPerInch :: Pizza -> Double
costPerInch (size, cost) = cost / areaGivenDiameter size

areaGivenDiameter :: Double -> Double
areaGivenDiameter size = pi * (size / 2) ** 2

describePizza :: Pizza -> String
describePizza (size, cost) =
  mconcat
    [ "The ",
      show size,
      " pizza is cheaper at ",
      show (costPerInch (size, cost)),
      " per square inch"
    ]

comparePizzas :: Pizza -> Pizza -> Pizza
comparePizzas p1 p2 =
  if costPerInch p1 < costPerInch p2
    then p1
    else p2

入出力結果(Terminal, Zsh)

% stack exec lesson-exe
"The 2.0 pizza is cheaper at 2.864788975654116 per square inch"
"The 2.0 pizza is cheaper at 2.864788975654116 per square inch"
"The 3.0 pizza is cheaper at 1.2732395447351628 per square inch"
"The 3.0 pizza is cheaper at 1.4147106052612919 per square inch"
"The 2.0 pizza is cheaper at 2.864788975654116 per square inch"
"The 2.0 pizza is cheaper at 3.183098861837907 per square inch"
"The 3.0 pizza is cheaper at 1.2732395447351628 per square inch"
"The 3.0 pizza is cheaper at 1.4147106052612919 per square inch"
"The 3.0 pizza is cheaper at 1.2732395447351628 per square inch"
"The 3.0 pizza is cheaper at 1.2732395447351628 per square inch"
"The 3.0 pizza is cheaper at 1.2732395447351628 per square inch"
"The 3.0 pizza is cheaper at 1.2732395447351628 per square inch"
"The 3.0 pizza is cheaper at 1.4147106052612919 per square inch"
"The 3.0 pizza is cheaper at 1.4147106052612919 per square inch"
"The 3.0 pizza is cheaper at 1.2732395447351628 per square inch"
"The 3.0 pizza is cheaper at 1.4147106052612919 per square inch"
%