ふつける(3) - 3章(2) map
3章後半はmapっす。
car,cdrを作ってみる
car,cdrが無いと思ったら、ナンダコレ!!
car :: [a] -> a car (x:xs) = x cdr :: [a] -> [a] cdr (x:xs) = xs
引数が分解出来ちゃうらしい。不思議な世界だ。
map
それがわかれば、mapは簡単で、
my_map :: (a -> b) -> [a] -> [b] my_map f [] = [] my_map f (x:xs) = f x : my_map f xs
しかし、謎過ぎる。
reverseを書いてみよう
mapの反復版だから、
my_reverse_iter :: [a] -> [a] -> [a] my_reverse_iter [] acc = acc my_reverse_iter (x:xs) acc = my_reverse_iter xs (x : acc) my_reverse :: [a] -> [a] my_reverse l = my_reverse_iter l []
出来た!!
(x:xs)はcar,cdrみたいな感じ。
length
簡単簡単。
my_length :: [a] -> Int my_length [] = 0 my_length (x:xs) = 1 + length xs
いいね。
foldrを書いてみる
右だから再帰で。
my_foldr :: (a -> b -> b) -> b -> [a] -> b my_foldr f acc [] = acc my_foldr f acc (x:xs) = f x (my_foldr f acc xs)
おし!!
foldlを書く
左は反復。
my_foldl :: (b -> a -> b) -> b -> [a] -> b my_foldl f acc [] = acc my_foldl f acc (x:xs) = my_foldl f (f acc x) xs
型がむじぃよ。
takeいきまっしょう。
そういえば、名前にhoge'が使えるんだった。
take' :: Int -> [a] -> [a] take' _ [] = [] take' 0 _ = [] take' n (x:xs) = x : take (n - 1) xs
_はなんでもいいらしい。
lastも。
ちょっと考えた。
last' :: [a] -> a last' [] = error "null list error." last' (x:[]) = x last' (x:xs) = last' xs
errorを覚えたよ!!
(x:[])なんて出来ちゃうのね。ifいらないっす。
reverseを使わず、最後のn要素を・・・とやりたいけど、思いつかず。考えてみる。
concatいこうぜ
平に。
concat' :: [[a]] -> [a] concat' [] = [] concat' (x:xs) = x ++ concat' xs
++か。
では++を
結構苦労したり。
append :: [a] -> [a] -> [a] append [] y = y append (x:xs) y = x : append xs y (+++) :: [a] -> [a] -> [a] (+++) x y = append x y
drop
最初のn個を切り落とす
drop' _ [] = [] drop' n (_:xs) | n <= 0 = xs | otherwise = drop' (n - 1) xs
ブロック使ってみた。
練習問題
'a'と'A'を入れ替えるswapa
main :: IO () main = do cs <- getContents putStr $ map swapa cs swapa :: Char -> Char swapa 'a' = 'A' swapa 'A' = 'a' swapa c = c
だいぶ慣れてきた。リスト楽しい。