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モジュールの拡張のようなものだった