Haskell
Menu Menu
関数型言語
関数とは、
入力から決まった出力を出す処理
のこと。
C でも関数って言うよね? C は関数型言語?
「やさしい Haskell 入門 (バージョン98)」 がお勧め。
関数型言語の特徴
理論がある
Operational Semantics ( 操作的意味論 )
C/Java だと メモリモデルとか byte code とか
関数型言語の場合は、式に対して決まる
λ計算、項書換え、π計算
型がある
型推論がある
Closure ( 関数と値の組 ) を持つ
lambda 式が、データ構造として使える
さらに Haskell だと
関数が状態をもたない (同じ入力には、常に同じ値が返る)
遅延評価
Outer most な引数評価順序
この反対を関数が副作用あるいは状態をもつと言う。
これらを、もっている場合もあるし、もってない場合もある。
どんなものがあるの?
Lisp () を多用する副作用のある言語、型推論はない (Scheme , Emacs Lisp , Common LISP)
ML 型推論をもつ副作用のある言語 (OCaml / SML)
Haskell 型推論をもつ副作用のない言語
Haskell
ghci
:help をまずやろう
:l プログラムの読み込み
:m moudle の読み込み
型を見れるようにする
:set +t
ghci の簡単な使い方
Prelude> 1+1
2
Prelude> 10/3
3.3333333333333335
変数への代入
Prelude> a = 1
<interactive>:1:2: parse error on input `='
let を使う (新しい変数の定義)
Prelude> let a = 1
Prelude> a
1
複数の変数を定義
Prelude> let a=1;b=2
Prelude> b
2
Prelude> a
1
Prelude> let a=3
Prelude> a
3
新しい変数 a が繰り返し作られる
Prelude> let a=3;a=5
<interactive>:1:4:
Conflicting definitions for `a'
Bound at: <interactive>:1:4
<interactive>:1:8
同じ変数に異なる辺りを代入すると怒られる。(単一代入、single assignment)
型がある
基本的な型
数値 Int
リスト [Int]
Pair (Int, [Int])
関数 Int -> Int
:t で見ることができます。
*Main> 1
1
it :: Integer
*Main> [1,2,3]
[1,2,3]
it :: [Integer]
*Main> "test"
"test"
it :: [Char]
*Main> head it
't'
it :: Char
*Main> tail "tail"
"ail"
it :: [Char]
*Main> let f x = x + 1
f :: (Num a) => a -> a
*Main> f 10
11
it :: Integer
List と 文字列
Prelude> :t 1
1 :: (Num t) => t
Prelude> :t [1,2,3]
[1,2,3] :: (Num t) => [t]
Prelude> :t "test"
"test" :: [Char]
Prelude> :t 'c'
'c' :: Char
[t] で、Num という型を要素とするリストという型だと思っている。
Prelude> :set +t
Prelude> 1
1
it :: Integer
Prelude> "test"
"test"
it :: [Char]
Prelude> ['t','e','s','t']
"test"
it :: [Char]
文字列は、Char を要素とするリスト
Prelude> :t [1,'c',4]
<interactive>:1:1:
No instance for (Num Char)
arising from the literal `1' at <interactive>:1:1
Possible fix: add an instance declaration for (Num Char)
In the expression: 1
In the expression: [1, 'c', 4]
型の混じったリストは作れない。
型推論がある
なので、型宣言はほとんどしない。現代的な言語は、ほとんどが型推論を持っているJavaScript や Python 、ruby のような言語でも実行時に型推論するのが普通
配列がない
Hash は書けない
二分木でやれ
遅延評価
Prelude> let c = getChar
c :: IO Char
Prelude> c
g'g'
it :: Char
Prelude> let b = c
b :: IO Char
Prelude> b
k'k'
it :: Char
getChar を代入した時点では、文字入力は要求されない。
c を表示しようとした時点で要求される。