コンテキストでの型の操作 do表記を使ってMonadを扱いやすくする do表記、糖衣構文、脱糖、>>=、>>、return、ラムダ式
入門Haskellプログラミング (Will Kurt(著)、株式会社クイープ(監修、翻訳)、翔泳社)のUNIT5(コンテキストでの型の操作)、LESSON 31(do表記を使ってMonadを扱いやすくする)、31.4(練習問題)Q31-1の解答を求めてみる。
コード
lesson/app/Main.hs
module Main (main) where
import Lib
( comparePizzas,
describePizza,
)
main :: IO ()
main =
return
"What is the size of pizza 1"
>>= putStrLn
>> getLine
>>= ( \size1 ->
return
"What is the cost of pizza 1"
>>= putStrLn
>> getLine
>>= ( \cost1 ->
return
"What is the size of pizza 2"
>>= putStrLn
>> getLine
>>= ( \size2 ->
return
"What is the cost of pizza 2"
>>= putStrLn
>> getLine
>>= ( \cost2 ->
( \pizza1 ->
( \pizza2 ->
( \betterPizza ->
return
( describePizza
betterPizza
)
>>= putStrLn
)
( comparePizzas
pizza1
pizza2
)
)
( read size2,
read cost2
)
)
( read size1,
read cost1
)
)
)
)
)
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
What is the size of pizza 1
5
What is the cost of pizza 1
10
What is the size of pizza 2
10
What is the cost of pizza 2
5
The 10.0 pizza is cheaper at 6.366197723675814e-2 per square inch
% stack exec lesson-exe
5
What is the size of pizza 1
What is the cost of pizza 1
1
What is the size of pizza 2
10
What is the cost of pizza 2
5
The 5.0 pizza is cheaper at 5.092958178940651e-2 per square inch
%