haskellで遊んでみた。
install
sudo aptitude install ghc6-doc haskell-mode
とりあえず、何か動かしてみる。
/usr/share/doc/ghc6-doc/index.htmlの中を見てみる。
Data.Listというもの発見*1
おおよそ、見当がついたの気がしたので使ってみる。
import Data.List l = take 5 [1..] ll = (take 3 (map (\x-> l) l)) append xs ys = xs ++ ys ave l = sum l `div` length l -- why this is error? "ave l = sum l / length l" cons x y = x : y ref l n = l !! n
1 + 2 -- => 3 [1..10] -- => [1,2,3,4,5,6,7,8,9,10] take 5 [1..] -- => [1,2,3,4,5] map (\x -> x * x) (take 4 [1..]) -- => [1,4,9,16] map (* 3) [1,2,3] -- => [3,6,9] map (/ 10) [1,2,3] -- => [0.1,0.2,0.3] map (100 /) [1,2,3] -- => [100.0,50.0,33.333333333333336] zipWith (+) [1,2,3] [10,10,10] -- => [11,12,13] zipWith (+) [1,2,3] [10,10] -- => [11,12] fibs = 0 : 1 : zipWith (+) fibs (tail fibs) [1,2] ++ [2,3] -- => [1,2,2,3] take 3 l -- => [1,2,3] append l l -- => [1,2,3,4,5,1,2,3,4,5] (++) l l -- => [1,2,3,4,5,1,2,3,4,5] l ++ l -- => [1,2,3,4,5,1,2,3,4,5] 100 : l -- => [100,1,2,3,4,5] cons 100 l -- => [100,1,2,3,4,5] head l -- => 1 tail l -- => [2,3,4,5] last l -- => 5 take 3 l -- => [1,2,3] drop 3 l -- => [4,5] splitAt 3 l -- => ([1,2,3],[4,5]) span (< 3) l -- => ([1,2],[3,4,5]) span (\x -> x < 3) l -- => ([1,2],[3,4,5]) l !! 4 -- => 5 ref l 4 -- => 5 (flip ref) 4 l -- => 5 length l -- => 5 [1,4..10] -- => [1,4,7,10] replicate 3 10 -- => [10,10,10] l -- => [1,2,3,4,5] sum l -- => 15 product l -- => 120 foldl (\a b -> a + b) 0 l -- => 15 foldl (+) 0 l -- => 15 msum l -- => 15 filter (< 3) l -- => [1,2] -- spanはtake,dropのようなもの(not like a filter) filter odd l -- => [1,3,5] -- partition odd l zip l l -- => [(1,1),(2,2),(3,3),(4,4),(5,5)] zip3 l l l -- => [(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5)] unzip (zip l l) -- => ([1,2,3,4,5],[1,2,3,4,5]) unzip3 (zip3 l l l) -- => ([1,2,3,4,5],[1,2,3,4,5],[1,2,3,4,5]) zipWith (+) l (tail l) -- => [3,5,7,9] concat (map (\x -> l) l) -- => [1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5] init l -- => [1,2,3,4] null l -- => False null [] -- => True import Data.List reverse l -- => [5,4,3,2,1] intersperse 10 l -- => [1,10,2,10,3,10,4,10,5] intercalate [10,10] (take 2 (List.map (\x -> l) l)) -- => [1,2,3,4,5,10,10,1,2,3,4,5] transpose ll -- => [[1,1,1],[2,2,2],[3,3,3],[4,4,4],[5,5,5]] foldl (+) 0 l -- => 15 foldl1 (+) l -- => 15 foldl1' (+) l -- => 15 and [True,True] -- => True or [False] -- => False all odd l -- => False any even l -- => True sum l -- => 15 product l -- => 120 maximum l -- => 5 minimum l -- => 1 scanl (+) 10 l -- => [10,11,13,16,20,25] scanl1 (*) [1..10] -- => [1,2,6,24,120,720,5040,40320,362880,3628800] mapAccumL (\x acc -> (x+acc, acc*2)) 0 l -- => (15,[2,4,6,8,10]) take 10 (iterate (+ 10) 0) -- => [0,10,20,30,40,50,60,70,80,90] take 5 (repeat 10) -- => [10,10,10,10,10] replicate 3 10 -- => [10,10,10] take 5 (cycle [1,2]) -- => [1,2,1,2,1] take 7 (unfoldr (\x -> Just (mod x 2, div x 2)) 77) -- => [1,0,1,1,0,0,1] foldr (\x acc -> (acc * 2) + x) 0 [1,0,1,1,0,0,1] -- => 77 takeWhile (< 3) l -- => [1,2] dropWhile (< 3) l -- => [3,4,5] span (< 3) l -- => ([1,2],[3,4,5]) break (> 3) l -- => ([1,2,3],[4,5]) --break/span, remove/filter? stripPrefix [2,3] l -- => Nothing stripPrefix [1,2] l -- => Just [3,4,5] stripPrefix "foo" "foobar" -- => Just "bar" group ((take 3 l) ++ (take 4 l) ++ l) -- => [[1],[2],[3],[1],[2],[3],[4],[1],[2],[3],[4],[5]] group [1,1,1,2,2,3,3,1] -- => [[1,1,1],[2,2],[3,3],[1]] inits l -- => [[],[1],[1,2],[1,2,3],[1,2,3,4],[1,2,3,4,5]] tails l -- => [[1,2,3,4,5],[2,3,4,5],[3,4,5],[4,5],[5],[]] isPrefixOf l l -- => True isPrefixOf [1,2] l -- => True isPrefixOf (tail l) l -- => False isSuffixOf [2,3] l -- => False isSuffixOf [4,5] l -- => True isInfixOf [2,3] l -- => True isInfixOf "haskell" "i'm in haskell world" -- => True elem 'a' "haskell" -- => True notElem '@' "haskell" -- => True lookup 3 (zip [1..] "haskell") -- => Just 's' --this is assoc in scheme find (== 3) l -- => Just 3 filter even l -- => [2,4] partition even l -- => ([2,4],[1,3,5]) elemIndex 3 l -- => Just 2 elemIndices 3 l -- => [2] elemIndices 3 (l++l++l) -- => [2,7,12] findIndex even l -- => Just 1 findIndex odd l -- => Just 0 findIndices even l -- => [1,3] -- zip,zip2....zip7 -- zipWith... -- unzip... zipWith (\x y -> (x,y)) [1..] "haskell" -- => [(1,'h'),(2,'a'),(3,'s'),(4,'k'),(5,'e'),(6,'l'),(7,'l')] lines "foo\nbar\nbaz" -- => ["foo","bar","baz"] words "i have a 'stream editor', what is this?" -- => ["i","have","a","'stream","editor',","what","is","this?"] unlines ["a", "b", "c"] -- => "a\nb\nc\n" unwords ["a", "b", "c"] -- => "a b c" nub (l ++ l) -- => [1,2,3,4,5] delete 2 l -- => [1,3,4,5] l \\ [1,2] -- => [3,4,5] take 10 (union l [1,3..] ) -- => [1,2,3,4,5,7,9,11,13,15] [1,3..10] `intersect` [1,2,3,4,5] -- => [1,3,5] sort [1,6,3,1,7,4,2,4] -- => [1,1,2,3,4,4,6,7] insert 3 l -- => [1,2,3,3,4,5] nubBy (\x y -> (odd x) == (odd y)) l -- => [1,2] -- deleteBy, unionBy, intersectBy, groupBy, sortBy, insertBy, -- genericLength :: Num i => [b] -> i -- genericTake :: Integral i => i -> [a] -> [a] -- genericDrop :: Integral i => i -> [a] -> [a] -- genericSplitAt :: Integral i => i -> [b] -> ([b], [b]) -- genericIndex :: Integral a => [b] -> a -> b -- genericReplicate :: Integral i => i -> a -> [a] reverse $ sort l -- => [5,4,3,2,1]
だいたい分かったので、ちょこっと関数を書いてみる。
fact 0 = 1 fact n = n * fact (n - 1) -- above definition and below definition is same meaning fact2 n = if n == 0 then 1 else n * fact (n - 1) -- even and odd is already defined evenp 0 = True evenp n = oddp (n - 1) oddp 0 = False oddp n = evenp (n -1) -- if <anything>' is strict definition(e.g. foldl'), then "merge_sort'" is bad name. merge_sort l = merge_sort' l where merge [] ys = ys merge xs [] = xs merge xs@(x:xr) ys@(y:yr) | x < y = x : (merge xr ys) | otherwise = y : (merge xs yr) merge_sort' [] = [] merge_sort' [x] = [x] merge_sort' l = let (left, right) = splitAt ((length l) `div` 2) l in merge (merge_sort left) (merge_sort right) -- permutation perm [x] = [[x]] perm s = concatMap (\x -> map (x :) (perm (delete x s))) s
todo
- "."と"$"の使い分け
- 分かったことをまとめる
- ポイントフリーの意味が分からない(色々調べている間に出てきた言葉だけど、調べていない)
*1:これはListモジュールの拡張のようなものだった