計算機科学のブログ

コンテキストでの型の操作 do表記を使ってMonadを扱いやすくする Monadの全てのインスタンスに対応させる、型シグネチャ

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

コード

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 =
    let costP1 = costPerInch p1
        costP2 = costPerInch p2
    in if costP1 < costP2
       then p1
       else p2

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

costs :: [Double]
costs = [18, 16]

sizes :: [Double]
sizes = [20, 15]

monadMain :: Monad m => m Double -> m Double -> m String
monadMain sizes costs = do
    size1 <- sizes
    cost1 <- costs
    size2 <- sizes
    cost2 <- costs
    let pizza1 = (size1, cost1)
    let pizza2 = (size2, cost2)
    let betterPizza = comparePizzas pizza1 pizza2
    return (describePizza betterPizza)

main :: IO ()
main = do
    let result = monadMain sizes costs
    print (length result)
    mapM_ print result

入出力結果(Terminal, Zsh)

% runghc sample3.hs
16
"The 20.0 pizza is cheaer at 5.729577951308232e-2 per square inch"
"The 20.0 pizza is cheaer at 5.092958178940651e-2 per square inch"
"The 20.0 pizza is cheaer at 5.729577951308232e-2 per square inch"
"The 20.0 pizza is cheaer at 5.729577951308232e-2 per square inch"
"The 20.0 pizza is cheaer at 5.092958178940651e-2 per square inch"
"The 20.0 pizza is cheaer at 5.092958178940651e-2 per square inch"
"The 20.0 pizza is cheaer at 5.092958178940651e-2 per square inch"
"The 20.0 pizza is cheaer at 5.092958178940651e-2 per square inch"
"The 20.0 pizza is cheaer at 5.729577951308232e-2 per square inch"
"The 20.0 pizza is cheaer at 5.092958178940651e-2 per square inch"
"The 15.0 pizza is cheaer at 0.10185916357881301 per square inch"
"The 15.0 pizza is cheaer at 9.054147873672269e-2 per square inch"
"The 20.0 pizza is cheaer at 5.729577951308232e-2 per square inch"
"The 20.0 pizza is cheaer at 5.092958178940651e-2 per square inch"
"The 15.0 pizza is cheaer at 9.054147873672269e-2 per square inch"
"The 15.0 pizza is cheaer at 9.054147873672269e-2 per square inch"
%