Preludeのつづきのつづきのつづき
昨日はfoldrまでやったので,今日はgcdから.
gcd
最大公約数を求める.ユークリッドの互除法を使うと簡単,ってのを以前結城さんの記事で読んだ記憶が.
gcd' :: Integral a => a -> a -> a gcd' m 0 = m gcd' m n = gcd' n (mod m n)
init
リストの末尾を除いたものを返す.ちょっとごり押しな感じもするけど,こんな感じかしら.
init' :: [a] -> [a] init' [x] = [] init' (x:xs) = x : init' xs
なんというか,
Main> init' "hello" "hell"
冗談みたいだ.
iterate
第一引数に一引数関数fをとりそれを,第二引数に適用,さらに適用されて出来たものにfを適用し,ってのを繰り返して無限リストを作る.
iterate' :: (a -> a) -> a -> [a] iterate' f a = a : iterate' f (f a)
簡単に書くと,こうか.ちゃんと動作している以上,これで問題無いみたいだな.
lcm
最小公倍数を求める.求め方は簡単.wikipediaの最小公倍数のページがオススメ.
lcm' :: Integral a => a -> a -> a lcm' a b = (a * b) `div` (gcd a b)
length
リストの長さを返す.
length' :: [a] -> Int length' [] = 0 length' (x:xs) = 1 + length' xs
これまたごり押し.
lex
lexical analyzerのlexかしら,文字列を読み込んで,はじめのスペースで区切る.なぜかタプルに入れて.型が良くわかんないので,どう書けば良いのやら.
Hugs.Base> lex "Stadium Arcadium Jupiter" [("Stadium"," Arcadium Jupiter")]
lines
Stringを引数に取って,改行文字で分けてリストにする.String型をどう処理すれば良いのか分かんないのでカンニング.
lines :: String -> [String] lines "" = [] lines s = let (l, s') = break (== '\n') s in l : case s' of [] -> [] (_:s'') -> lines s''
えぇ,こんなんワカンネェよ,だけど全て知ってる手続き.でも,このletの使い方は初めてだ.
どうなってるんだろう.
- breakを実行.breakは,条件が一致した所でリストをちょん切るんだよね.
- sを\nでちょん切って,それを(l, s')ってタプルにletで入れてるのか.なるほど,ちょん切った前半をlに入れて,後半をs'に入れてるのか.
- そしてinに移り,ちょん切った後半のs'が空のリストなら,空のリストを返す.空じゃなかったら,_(ワイルドカード)すなわち\nより後ろをlines関数に渡してるんだな!
良く出来てるなぁ.
lookup
第一引数と,第二引数の要素2個のタプルのリストのfstを比較.一致したらそのsndを返す.うへぇ,何書いてるのか分かんないから実際に書いてみるか.
lookup' :: Eq a => a -> [(a,b)] -> Maybe b lookup' _ [] = Nothing lookup' a (x:xs) | a == (fst x) = Just (snd x) | otherwise = lookup a xs
うん,コードの方が,駄文より幾らか分かり易いな.このMaybeってのオモロい.
Main> :t Nothing Nothing :: Maybe a Main> Nothing Nothing Main> :t Just Just :: a -> Maybe a Main> Just 1 Just 1
何がしたいねん!!
map
おなじみmap.
map' :: (a -> b) -> [a] -> [b] map' _ [] = [] map' f (x:xs) = f x : map' f xs
あんなに便利なのに簡単だ.よし,今日はコレぐらいで.