Haskell 入門


Haskell ワンライナー

以前の記事の「Haskell ワンライナー」の実行例が Hugs 版で見づらかったので ghci 版で記述してみた。ghci でマルチラインを使うためには、:set +m コマンドでマルチライン対応にしておく。マルチラインを解消するには :unset +m と入力する。

Prelude> :set +m

定番の階乗の計算(再帰関数)

Prelude> let
Prelude| fact 0 = 1
Prelude| fact n = n * fact (n-1)
Prelude|
Prelude> fact 5
120

フィボナッチ数(無限数列)

Prelude> let fib = 0:1:zipWith (+) fib (tail fib)
Prelude|
Prelude> take 10 fib
[0,1,1,2,3,5,8,13,21,34]

素数(内包的定義)

Prelude> let sieve (x:xs) = x : sieve [y | y <- xs, y `mod` x /= 0]
Prelude|
Prelude> take 10 $ sieve [2..]
[2,3,5,7,11,13,17,19,23,29]

順列( concat の使用例)

Prelude> :m Data.List
Prelude Data.List> let
Prelude Data.List| perm [] = [[]]
Prelude Data.List| perm xs = concat [map (x:) $ perm (delete x xs)| x <- xs]
Prelude Data.List|
Prelude Data.List> perm "abc"
["abc","acb","bac","bca","cab","cba"]

組み合わせ(引数が2つの場合の再帰関数)

Prelude Data.List> let
Prelude Data.List| comb _ 0 = [[]]
Prelude Data.List| comb [] _ = []
Prelude Data.List| comb (x:xs) n = map (x:) (comb xs (n-1)) ++ comb xs n
Prelude Data.List|
Prelude Data.List> comb "abcd" 2
["ab","ac","ad","bc","bd","cd"]

配列の長さ(ワイルドカード _ の使い方)

Prelude Data.List> let
Prelude Data.List| mylength [] = 0
Prelude Data.List| mylength (_:xs) = 1 + mylength xs
Prelude Data.List|
Prelude Data.List> mylength [1,2,3]
3

クイックソート(左右の再帰)

Prelude Data.List> let
Prelude Data.List| qsort [] = []
Prelude Data.List| qsort (x:xs) = qsort (filter (<x) xs) ++ [x] ++ qsort (filter (>= x) xs)
Prelude Data.List|
Prelude Data.List> qsort "world"
"dlorw"

要素の挿入( let 〜 in 構文の使い方)

Prelude Data.List> let
Prelude Data.List| insertAt x xs n =
Prelude Data.List| let (ys,zs) = splitAt n xs
Prelude Data.List| in ys ++ [x] ++ zs
Prelude Data.List|
Prelude Data.List> insertAt 'X' "abcd" 2
"abXcd"

Maybe モナド(モナドのプログラム)

Prelude Data.List> let double x = 2 * x
Prelude Data.List|
Prelude Data.List> Just 2 >>= return . double
Just 4

IOモナド(入出力の基本)

Prelude Data.List> do
Prelude Data.List| cs <- getLine
Prelude Data.List| putStrLn cs
Prelude Data.List|
hello, world
hello, world

ファイルの書き込み( writeFile 関数の使い方)

Prelude Data.List> writeFile "test.txt" "hello, world"

ファイルの読み込み( readFile 関数の使い方)

Prelude Data.List> readFile "test.txt" >>= putStrLn
hello, world

データのシリアライズ( show 関数の使い方)

Prelude Data.List> writeFile "array.txt" (show [1,2,3])
Prelude Data.List> readFile "array.txt" >>= putStrLn
[1,2,3]

データの読み出し( read 関数の使い方)

Prelude Data.List> readFile "array.txt" >>= print . sum . (read :: String -> [Int])
6