挿入ソート
単純なソートアルゴリズム.
計算量は O(n2).
- 空リストは整列されているものとする
- 整列しているリストに対して,1つの要素を正しい場所に挿入する
insert :: Ord a => a -> [a] -> [a] insert x [ ] = [x] insert x (y:ys) | x <= y = x : y : ys | otherwise = y : insert x ys isort :: Ord a => [a] -> [a] isort [ ] = [ ] isort (x:xs) = insert x (isort xs)
マージソート
ボトムアップの分割統治法を用いたソートアルゴリズム.
データを分割する
各々をソートする
マージする
以下 haskell の実装(安定ソートではない)
merge :: Ord a => [a] -> [a] -> [a] merge [ ] [ ] = [ ] merge xs [ ] = xs merge [ ] ys = ys merge (x:xs) (y:ys) | x <= y = x : merge xs (y:ys) | otherwise = y : merge (x:xs) ys msort :: Ord a => [a] -> [a] msort [ ] = [ ] msort [x] = [x] msort xs = merge (msort (take center xs)) (msort (drop center xs)) where center = div (length xs) 2
ユークリッドの互除法
ユークリッドの互除法は,2つの自然数または整数の最大公約数(Greatest Common Divisor)を求めるアルゴリズムです.
入力を m, n (m ≧ n) とする。
n = 0 なら、 m を出力してアルゴリズムを終了する。
m を n で割った余りを新たに n とし、更に 元のnを新たにm とし 2. に戻る。
gcd :: Int -> Int -> Int gcd m n | m < n = gcd n m | n == 0 = n | otherwise = gcd n (mod m n)
最小公倍数と最大公約数の以下の関係から,
最小公倍数(Least Common Multiple)を用意に求められる.
gcd(a, b) * lcm(a, b) = a * b
lcm :: Int -> Int -> Int lcm m n = m * n / gcd m n
CoffeeScript のカリー化
個人的に CoffeeScript が再燃してる今日このごろ.
CoffeeScript の関数定義はこんな感じ
# CoffeeScript add = (a, b) -> a + b // JavaScript var add; add = function(a, b) { return a + b; };
続いてカリー化してみる
add = (a) -> (b) -> a + b add(2)(3) # 5
最近 Haskell にはまってるんで,できればこんな感じで呼び出したい.
add :: Num a=> a -> a -> a add a b = a + b main = print (add 2 3) -- 5
いろいろ試してみる...
# OK add(2)(3) add(2) 3 (add 2)(3) (add 2) 3 # Error add 2(3) add 2 3 # OK increment = add(1) increment 3 # 4
結論
Haskell っぽく呼ぶのは無理っぽい.
add(2)(3)
これがベターなのか.
Haskell の複数の引数を渡す関数の型
複数の引数を渡す関数には、例えば和を求める関数があげられる.
add x y = x + y
これの型を調べると以下のようになる.
> :t add add :: Int -> Int -> Int
Int と Int を引数にとって, Int を返す関数なのだが、
いまいち複数の引数を取っている感が無い.
先日紹介した,「プログラミング Haskell」(邦題 : Programming in Haskell) 3.6 章の解説でようやく理解できた.
そもそも複数の引数を取るというのが間違いであり,カリー化されていただけだ。
先程の型に括弧をつけると以下のようになる.
add :: Int -> (Int -> Int)
つまり,Int 型の引数を一つ取り,"Int 型の引数を取りInt型を返す関数"を返す型ということだ.
カリー化の考案者を Haskell Curry だと勘違いしていました.
実際は Gottlob Frege という人らしい.(wiki)