ふつける(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

演算子再帰的定義がわからず。appendを介してみた。

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


だいぶ慣れてきた。リスト楽しい。