Haskell のループと言うと何でも再帰させてしまいます。
map、fold もあるのですが、特にリスト内包表記は使っていませんでした。
フィボナッチ数 1つがいの兎は、産まれて2か月後から毎月1つがいずつの兎を産む。 1つがいの兎は1年の間に何つがいの兎になるか?
フィボナッチ数を求めてみます。
data PairOfRabbits = Rabbits {age::Integer} deriving Show -- 1ヶ月後のつがいの兎 -- 引数に1ヶ月後のつがいの兎をとり、産まれて2か月未満なら -- 年齢を加算し、それ以上なら年齢を加算したうえに新しい兎を返します。 nextMonth :: PairOfRabbits -> [PairOfRabbits] nextMonth (Rabbits y) | y < 1 = [Rabbits{age=y+1}] | otherwise = [Rabbits{age=y+1}, Rabbits{age=0}] -- 1ヶ月後の兎小屋:再帰ループによる適用 -- 兎小屋をリストで表現します。兎小屋にいる兎に1ヶ月後の状態を適用します。 nextHouse :: [PairOfRabbits] -> [PairOfRabbits] nextHouse [] = [] nextHouse (x:xs) = nextMonth x ++ nextHouse xs -- 1ヶ月後の兎小屋:リスト内包表記による適用 nextHouse' :: [PairOfRabbits] -> [PairOfRabbits] nextHouse' rabbits = concat [nextMonth n | n <- rabbits] -- 1ヶ月後の兎小屋:mapによる適用 nextHouse2 :: [PairOfRabbits] -> [PairOfRabbits] nextHouse2 = concat . map nextMonth take 12 $ map length $ iterate nextHouse [Rabbits{age=0}] -- > [1,1,2,3,5,8,13,21,34,55,89,144] take 12 $ map length $ iterate nextHouse' [Rabbits{age=0}] -- > [1,1,2,3,5,8,13,21,34,55,89,144] take 12 $ map length $ iterate nextHouse2 [Rabbits{age=0}] -- > [1,1,2,3,5,8,13,21,34,55,89,144]