[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 自習
propella home