Prelude

HaskellのPreludeのなかで比較的簡単そうなの(Monadoとか含まないとか、sin,cosみたいにプリミティブじゃないやつ)を自分で実装してみた。
結構勉強になるかも。


...いや、ふつける欲しいんだけどさ。金無くね...。
まぁ秋休みでやや食費浮くのでその分ふつけるに回してもいいのだけど...


とりあえず何も見ずに、型と実行結果、名前などから機能を類推して自分で実装
その後http://www.sampou.org/haskell/report-revised-j/standard-prelude.htmlで答え合わせ
と言った感じで。

で、動作も完璧、これでok!!とか自信満々に答え見に行くともっと簡単に実装されてるっていうね...
結構ショック。
でもかなり美しい。思わず納得。


...ソースコードみて美しいとかいい始めたら末期だな...。

以下自分の回答が大きく外してる例 / 美しいと思った実装を↓

and

_and [] = True
_and (True:bs) = and bs
_and _ = False


模範回答

_and = foldr (&&) True

fold系強すぎ...。

break

_break f x = let
     _break' f' (x':xs') acc' = if f' x'
                             then (acc',(x':xs'))
                             else _break' f' xs' (acc'++[x'])
             in _break' f x []

苦肉の策の局所宣言。


模範回答(実際にはspanに(not p)を与えてるのですが...

_break :: (a -> Bool) -> [a] -> ([a],[a])
_break p (x:xs)
	| p x		= ([], x:xs)
	| otherwise	= (x:xs', xs'')
		where (xs',xs'') = _break p xs

美しいなぁ...

concatMap

_concatMap p = foldr (\a b -> (p a) ++ b) [];

concatのコードを少し変えるだけで出来るはずだ!とか思ってやったら


模範回答

_concatMap f = concat . map f

そのまんまconcat利用してました...

lines

模範回答

_lines :: String -> [String]
_lines s = let (l,s') = break (== '\n') s
		in l : case s' of
			[]	-> []
			(_:s'')	-> _lines s''

さっぱり分からず最初から答えを見に。
美しいなぁ...

reverse

_reverse xs = let
	_reverse' [] zs = zs
	_reverse' (y:ys) zs = _reverse' ys (y:zs) in
	_reverse' xs []

たしかreverseはアキュームレータ使ったの作ってから作った方が楽なはず!!とか授業でやったな、とか思って実装するも...


模範回答

_reverse = foldl (flip (:)) []

またfoldか!!
にしてもうまいなぁ...

splitAt

_splitAt n xs | n <= 0		= ([], xs)
_splitAt n (x:xs) = (x:ys, zs)
			where (ys, zs)	= _splitAt (n-1) xs

これは美しくできた!!とか思って絶賛自画自賛


模範回答

_splitAt n xs = (take n xs, drop n xs)

...そりゃないよ...(д

unlines

_unlines [] = []
_unlines (x:xs) = x ++ "\n" ++ _unlines xs


模範回答

_unlines = concatMap (++ "\n")

ぬ、ぬぅ。確かに考えてみれば...。Stringは[Char]なんだし...。

unzip

_unzip [] = ([], [])
_unzip ((x, y):xys) = (x:xs, y:ys)
			where (xs, ys) = _unzip xys

これは美しく決まった!とか絶賛自画自賛。(splitAtとまったく同じw


模範回答

_unzip = foldr (\(a, b) ~(as, bs) -> (a:as, b:bs)) ([], [])

foldか...そだよね...。
ちなみにこの「~」が未だ謎。「~」の動作は一応は理解...というか「知った」が...。
必須なんだろうか...。そもそも型的にタプル以外来る訳ないし...。そもそも束縛失敗したら関数全体が?ん?よく分からん
やはり「~」が理解できてなさげ。

zip

_zip [] _		= []
_zip _ []		= []
_zip (x:xs) (y:ys)	= (x, y) : _zip	xs ys

これ以外に書き方無くないか?とか思ってたら


模範回答

_zip = zipWith (,)

zipWithはまだやってねーよ!!(ascii順で一個終わる毎に答え合わせしてた。



てな感じでpreludeをざっと。
haskellおもしろい!!