計算機科学のブログ

コンテキストでの型の操作 Monad型クラス do表記を使ってMonadを扱いやすくする 脱糖、>>=、>>、return、ラムダ式

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

空のリストにも対処する。空のリストを返す。

実際に確認。

コード

type Pizza = (Double, Double)

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

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

comparePizzas :: Pizza -> Pizza -> Pizza
comparePizzas p1 p2 =
  ( \costP1 costP2 ->
      if costP1 < costP2
        then p1
        else p2
  )
    (costPerInch p1)
    (costPerInch p2)

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

main :: IO ()
main =
  putStrLn "What is the size of pizza 1"
    >> getLine
    >>= ( \size1 ->
            putStrLn "What is the cost of pizza 1"
              >> getLine
              >>= ( \cost1 ->
                      putStrLn "What is the size of pizza 2"
                        >> getLine
                        >>= ( \size2 ->
                                putStrLn "What is the cost of pizza 2"
                                  >> getLine
                                  >>= ( \cost2 ->
                                          ( \pizza1 ->
                                              ( \pizza2 ->
                                                  ( \betterPizza ->
                                                      putStrLn $ describePizza betterPizza
                                                  )
                                                    ( comparePizzas
                                                        pizza1
                                                        pizza2
                                                    )
                                              )
                                                (read size2, read cost2)
                                          )
                                            (read size1, read cost1)
                                      )
                            )
                  )
        )

入出力結果(Terminal, Zsh)

% runghc sample1.hs
What is the size of pizza 1
10
What is the cost of pizza 1
5
What is the size of pizza 2
20
What is the cost of pizza 2
10
The 20.0 pizza is cheaper at 3.183098861837907e-2 per square inch
% runghc sample1.hs
What is the size of pizza 1
10
What is the cost of pizza 1
1
What is the size of pizza 2
20
What is the cost of pizza 2
100
The 10.0 pizza is cheaper at 1.2732395447351627e-2 per square inch
%