by shigemk2

当面は技術的なことしか書かない

再帰

引数が空や、マイナスなど、想定外の値のときの結果を考慮しつつ、
再帰を行う。

-- リストのtail部分を引数として再帰を行う
maximum' :: (Ord a) => [a] -> a
maximum' [] = error "maximum of empty list"
maximum' [x] = x
maximum' (x:xs) = max x (maximum' xs)

-- (n-1)回だけ繰り返したxのリストをtailとして構築する
replicate' :: Int -> a -> [a]
replicate' n x
  | n <= 0 = []
  | otherwise = x : replicate' (n-1) x

-- リストからn要素取り出したものは、xを1つ目の要素にして、xsからn-1要素を取りだしたリストを残りの要素にしたリストと同じである
take' :: Int -> [a] -> [a]
take' n _
  | n <= 0 = []
take' _ [] = []
take' n (x:xs) = x : take' (n-1) xs

-- tailを逆順にして、後ろにheadをくっつける
reverse' :: [a] -> [a]
reverse' [] = []
reverse' (x:xs) = reverse' xs ++ [x]

repeat' :: a -> [a]
repeat' x = x : repeat' x

-- x と y のheadをペアにして、tailを再帰
zip' :: [a] -> [b] -> [(a,b)]
zip' _ [] = []
zip' [] _ = []
zip' (x:xs) (y:ys) = (x,y) : zip' xs ys

elem' :: (Eq a) => a -> [a] -> Bool
elem' a [] = False
elem' a (x:xs)
  | a == x = True
  | otherwise = a `elem` xs

結果

Main> maximum' [2,5,1]
5
Main> replicate' 5 2
[2,2,2,2,2]
Main> take' 4 [1,2,3,4]
[1,2,3,4]
Main> take' 5 [1,2,3,4]
[1,2,3,4]
Main> reverse' [1,2,3,4,5]
[5,4,3,2,1]
Main> repeat' 3
[3,3,3,...,3,Interrupted.
Main> zip' [1,2,3] [4,3,2,1]
[(1,4),(2,3),(3,2)]
Main> elem' 5 [1,2,3]
False