2013年10月24日木曜日

開発環境

『初めてのプログラミング 第2版』(Chris Pine 著、長尾 高弘 訳、オライリー・ジャパン、2010年、ISBN978-4-87311-469-9)の13章(新しいクラスの作成と既存クラスの変更), 13.2(クラスの作り方)、13.3(インスタンス変数)、13.4(newとinitialize)、13.5(ベビードラゴンゲーム)、13.6(練習問題の続き)、オレンジの木をHaskellで解いてみる。

その他参考書籍

Haskellだと組み込みクラスとかオブジェクトとかRubyと考え方が違うので、前問と同様にとりあえずモジュールを作ったり、自作の新しい型を作ったりしてみる。

型を作る。

コード(BBEdit)

Sample.hs

{-# OPTIONS -Wall -Werror #-}

import OrangeTree

main :: IO ()
main = do
    putStrLn "オレンジの木を植えました。"
    let ot = OrangeTree True 0 0 0
    pass 11 ot

pass :: Int -> OrangeTree -> IO ()
pass a b = do
    if a == 0
    then return ()
    else do
        putStrLn "1年経過しました。"
        let c = oneYearPasses b
        putStrLn $ orangeTreeState c
        let n = orangeCount c
        pick (n + 1) c
        pass (a - 1) c

pick :: Int -> OrangeTree -> IO ()
pick a b = do
    if a == 0
    then return ()
    else do let c = pickAnOrange b
            putStrLn $ snd c
            pick (a - 1) $ fst c

コード(BBEdit)

OrangeTree.hs

{--
{-# OPTIONS -Wall -Werror #-}
--}

module OrangeTree
( OrangeTree (..),
  oneYearPasses,
  pickAnOrange,
  orangeTreeState,
) where

data OrangeTree = OrangeTree {alive :: Bool,
                              height :: Int, 
                              orangeCount :: Int, 
                              age :: Int} deriving (Show)

oneYearPasses :: OrangeTree -> OrangeTree
oneYearPasses (OrangeTree False _ _ _) = OrangeTree False 0 0 0
oneYearPasses (OrangeTree _ _ _ 10) = OrangeTree False 0 0 0
oneYearPasses (OrangeTree a b c d)
    | d < 4 = OrangeTree a (b + 1) c (d + 1)
    | otherwise = OrangeTree a (b + 1) (d - 3) (d + 1)

pickAnOrange :: OrangeTree -> (OrangeTree, String)
pickAnOrange (OrangeTree {alive = False}) =
    (OrangeTree {alive = False}, "木はもう枯れているので実は採れません。")
pickAnOrange (OrangeTree a b c d)
    | d < 5 = (OrangeTree a b c d, "まだ樹齢" ++ (show d) ++ 
                                   "なので採れる実はありません。")
    | c > 0 = (OrangeTree a b (c - 1) d,
               "とてもおいしいオレンジの実が採れました。")
    | otherwise = (OrangeTree a b c d, "今年はもう採れる実がありません。")

orangeTreeState :: OrangeTree -> String
orangeTreeState a = "高さ: " ++ (show $ height a) ++
                   " 実の数: " ++ (show $ orangeCount a)

入出力結果(Terminal, runghc)

$ runghc Sample.hs

OrangeTree.hs:26:6: Warning:
    Fields of `OrangeTree' not initialised: height, orangeCount, age
    In the expression: OrangeTree {alive = False}
    In the expression:
      (OrangeTree {alive = False}, 
       "\26408\12399\12418\12358\26543\12428\12390\12356\12427\12398\12391\23455\12399\25505\12428\12414\12379\12435\12290")
    In an equation for `pickAnOrange':
        pickAnOrange (OrangeTree {alive = False})
          = (OrangeTree {alive = False}, 
             "\26408\12399\12418\12358\26543\12428\12390\12356\12427\12398\12391\23455\12399\25505\12428\12414\12379\12435\12290")
オレンジの木を植えました。
1年経過しました。
高さ: 1 実の数: 0
まだ樹齢1なので採れる実はありません。
1年経過しました。
高さ: 2 実の数: 0
まだ樹齢2なので採れる実はありません。
1年経過しました。
高さ: 3 実の数: 0
まだ樹齢3なので採れる実はありません。
1年経過しました。
高さ: 4 実の数: 0
まだ樹齢4なので採れる実はありません。
1年経過しました。
高さ: 5 実の数: 1
とてもおいしいオレンジの実が採れました。
今年はもう採れる実がありません。
1年経過しました。
高さ: 6 実の数: 2
とてもおいしいオレンジの実が採れました。
とてもおいしいオレンジの実が採れました。
今年はもう採れる実がありません。
1年経過しました。
高さ: 7 実の数: 3
とてもおいしいオレンジの実が採れました。
とてもおいしいオレンジの実が採れました。
とてもおいしいオレンジの実が採れました。
今年はもう採れる実がありません。
1年経過しました。
高さ: 8 実の数: 4
とてもおいしいオレンジの実が採れました。
とてもおいしいオレンジの実が採れました。
とてもおいしいオレンジの実が採れました。
とてもおいしいオレンジの実が採れました。
今年はもう採れる実がありません。
1年経過しました。
高さ: 9 実の数: 5
とてもおいしいオレンジの実が採れました。
とてもおいしいオレンジの実が採れました。
とてもおいしいオレンジの実が採れました。
とてもおいしいオレンジの実が採れました。
とてもおいしいオレンジの実が採れました。
今年はもう採れる実がありません。
1年経過しました。
高さ: 10 実の数: 6
とてもおいしいオレンジの実が採れました。
とてもおいしいオレンジの実が採れました。
とてもおいしいオレンジの実が採れました。
とてもおいしいオレンジの実が採れました。
とてもおいしいオレンジの実が採れました。
とてもおいしいオレンジの実が採れました。
今年はもう採れる実がありません。
1年経過しました。
高さ: 0 実の数: 0
木はもう枯れているので実は採れません。
$

0 コメント:

コメントを投稿