計算機科学のブログ

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

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

コード

lesson/app/Main.hs

module Main (main) where

import Lib
  ( comparePizzas,
    describePizza,
  )

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

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

listMain :: [String]
listMain = do
  size1 <- sizeData
  cost1 <- costData
  size2 <- sizeData
  cost2 <- costData
  return $
    describePizza $
      comparePizzas
        (size1, cost1)
        (size2, cost2)

main :: IO ()
main = do
  mapM_ print listMain

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"
%