[View] [Edit] [Attachments] [History] [Home] [Changes] [Search] [Help]
Haskell
haskell の基本的な使い方
インストールなど
僕は http://www.sampou.org/haskell/ からリンクを辿ってダウンロード/
インストールを行いました。Windows で使う場合は、meadow から使うと
補完が効いて便利です。
ln -s /cygdrive/c/Program\ Files/Hugs98/hugs.exe /usr/local/bin/
勉強の為のリンク
シェル
$ hug
でシェルに入ります。四則演算などは括弧も含めて普通にできるので、
電卓として使えます。ファイルに記述した関数定義を読み込むには
> :load "ファイル名.hs"
のようにします。コメントは -- です。
関数
haskell では、シェル内で関数を定義する事は出来ないようです。
関数を使いたい場合、where の後ろに定義を書く事によってその1行の
中で使えます。
一件アホくさいですが、足し算をする関数 add を定義してみます。
> add 10 3 where add a b = a + b
add a b = a + b が関数定義、add 10 3 が、その関数を使っている部分です。
> fact 5 where fact 1 = 1 ; fact n = n fact (n - 1)
今度は階乗。全部シェル内でやろうとしているので見栄えが悪いですが、この中で
fact 1 = 1
fact n = n fact (n - 1)
が階乗の定義です。; で区切って複数の定義を書く事が出来ます。つまり、
引数が 1 なら必ず 1、それ以外は n fact (n - 1) であるという再帰的な
定義になっています。
次はフィボナッチ数です。これは難しいので順番に考えます。
> fib 1 where fib 1 = 1
1 -- 最初のフィボナッチ数は1です。
> fib 1 where fib 1 = 1; fib 2 = 1
1 -- 2番目のフィボナッチ数も1です。
> fib 3 where fib 1 = 1; fib 2 = 1; fib 3 = fib 1 + fib 2
2 -- 3番目のフィボナッチ数は、fib 1 + fib 2 です。
> fib 4 where fib 1 = 1; fib 2 = 1; fib n = fib (n - 2) + fib (n - 1)
3 -- という事は、n番目のフィボナッチ数は fib (n - 2) + fib (n - 1)です。
リスト
タプル(配列? 固定長)は()、リスト(任意長)は[]で囲みます。
(1,2,3) タプル
[1,2,3] リスト
1: [2,3] [1,2,3] を表すリスト
[1..10] 1から10までのリスト
[1,3..] 奇数を表す無限リスト
このように、リストを使うと無限を表現する事が出来ます。
また、リストには2つの表記法があり、[1,2,3] と、1:2:3:[] は同じ意味です。
1:2:3:[] の方がリストの実際上のメモリ上の形を反映しているといえます。
プログラム
複数行に渡ってプログラムを書いていく為には、必ずファイルに保存する必要が
あります。haksell プログラムの拡張子は .hs です。例えば Fib.hs という名前で、
と保存すると、上のフィボナッチ数列のプログラムが出来ます。
module Fib where
fib 1 = 1
fib 2 = 1
fib n = fib (n - 2) + fib (n - 1)
ここで、カラム位置にやけにうるさいので注意してください。
レイアウトという機能により、毎行 ; を書かなくても良い一方で、
書式にイロイロ決まりがあるようです。
プログラムを読み込んで実行するには、hugs シェルで
> :load fib.hs
> fib 10
のようにします。
便利な関数 http://www.teu.ac.jp/kougi/koshida/Prog6/text04.htmlより
: a -> [a] -> [a] リストの先頭に要素を1個追加する.
1:[2,3] ⇒ [1,2,3]
++ [a] -> [a] -> [a] リストの連結
"Kos" ++ "hida" ⇒ "Koshida"
!! [a] -> Int -> a xs!!nは,リストxsの第n要素を返す.
ただし,先頭要素は第0要素である.
[14, 7, 3]!!1 ⇒ 7
concat [[a]] -> [a] リストを要素とするリストの各要素を連結.
concat [[2,3],[],[1]] ⇒ [2,3,1]
length [a] -> Int リストの長さ.
length "Koshida" ⇒ 7
head,last [a] -> a リストの先頭(最終)要素.
head "Koshida" ⇒ 'K'
last "Koshida" ⇒ 'a'
tail,init [a] -> [a] 先頭(最終)要素を除いたリスト.
tail "Koshida" ⇒ "oshida"
init "Koshida" ⇒ "Koshid"
replicate Int -> a -> [a] 同じ要素をn回繰り返したリスト.
replicate 3 'w' ⇒ "www"
take Int -> [a] -> [a] 先頭からn要素を取り出したリスト.
take 3 "Koshida" ⇒ "Kos"
drop Int -> [a] -> [a] 先頭のn要素を取り除いたリスト.
drop 3 "Koshida" ⇒ "hida"
splitAt Int -> [a] -> ([a],[a]) リストを与えられた箇所で分割する.
splitAt 3 "Koshdia" ⇒ ("Kos", "hida")
reverse [a] -> [a] リスト要素の順序を反転
reverse [1,2,3] ⇒ [3,2,1]
zip [a] -> [b] -> [(a,b)] 二つのリストを,ペアのリストに変換.
zip [1,2] [3,4,5] ⇒ [(1,3),(2,4)]
unzip [(a,b)] -> ([a],[b]) ペアのリストを,二つのリストに分解.
unzip [(1,3),(2,4)] ⇒ ([1,2],[3,4])
and [Bool] -> Bool 全要素のAND
and [True,False,True] ⇒ False
or [Bool] -> Bool 全要素のOR
or {True, False, True] ⇒ True
sum [Int] -> Int 数値リストの全要素の和
[Float] -> Float sum [1,2,3,4] ⇒ 10
product [Int] -> Int 数値リストの全要素の積
[Float] -> Float product [1,2,3,4] ⇒ 24
Haskell 自習