計算機科学のブログ

コードの整理とプロジェクトのビルド Monad型クラス stackを使ってプロジェクトをビルドする リファクタリング

入門Haskellプログラミング (Will Kurt(著)、株式会社クイープ(監修、翻訳)、翔泳社)のUNIT6(コードの整理とプロジェクトのビルド)、LESSON35(stackを使ってプロジェクトをビルドする)、35.6(練習問題)Q36-2の解答を求めてみる。

コード

app/Main.hs

module Main where

import Lib

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

コード

src/Lib.hs

module Lib
  ( comparePizzas,
    describePizza,
  )
where

type Pizza = (Double, Double)

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 cheaper at ",
          show costSqInch,
          " per square inch"
        ]

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

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

入出力結果(Terminal, Zsh)

% stack setup
stack will use a sandboxed GHC it installed
For more information on paths, see 'stack path' and 'stack exec env'
To use this GHC and packages outside of a project, consider using:
stack ghc, stack ghci, stack runghc, or stack exec
% stack build
Building all executables for `pizza' once. After a successful build of all of them, only specified executables will be rebuilt.
pizza> build (lib + exe)
Preprocessing library for pizza-0.1.0.0..
Building library for pizza-0.1.0.0..
Preprocessing executable 'pizza-exe' for pizza-0.1.0.0..
Building executable 'pizza-exe' for pizza-0.1.0.0..
[1 of 2] Compiling Main
[2 of 2] Compiling Paths_pizza
Linking .stack-work/dist/x86_64-osx/Cabal-3.2.1.0/build/pizza-exe/pizza-exe ...
pizza> copy/register
Installing library in /Users/…/pizza/.stack-work/install/x86_64-osx/160203b3c1b5851ee38cefff1898f2ea31f9dd27504c585eee0da67dd7dc8bb2/8.10.7/lib/x86_64-osx-ghc-8.10.7/pizza-0.1.0.0-Df0re6Kpq6wDl0tkzY20xK
Installing executable pizza-exe in /Users/…/pizza/.stack-work/install/x86_64-osx/160203b3c1b5851ee38cefff1898f2ea31f9dd27504c585eee0da67dd7dc8bb2/8.10.7/bin
Registering library for pizza-0.1.0.0..
% stack exec pizza-exe
What is the size of pizza 1
12
What is the cost of pizza 2
15
What is the size of pizza 1
28
What is the cost of pizza 2
20
The 28.0 pizza is cheaper at 3.248060063099905e-2 per square inch
% stack exec pizza-exe
What is the size of pizza 1
12
What is the cost of pizza 2
15
What is the size of pizza 1
18
What is the cost of pizza 2
20
The 18.0 pizza is cheaper at 7.859503362562734e-2 per square inch
%