ka (kaosfield)
自分自身の復習や予習も兼ねてのスライドです
間違いや勘違いが含まれる可能性が多分にあります
値の集合の形
関数自体も無名関数が即時に作れて変数に代入したり出来るので値である
フォン・ノイマン型の世界においてはプログラム自体がメモリ上に格納されて変化しうる単なる値であるとも考えられる
int double(int x)
{
return x * 2;
}
これの型は\(Integer → Integer\)と書く
string toString(int x) {
return toString(x);
}
これの型は\(Integer → String\)と書く
function f(g) {
return g(1) * g(2)
}
function g1(x) {
return x + 1
}
function g2(x) {
return x * 2
}
g1とg2の型は \(Integer → Integer\)
fの型は\(Integer → Integer\)を引数にして\(Integer\)を返すので
\((Integer → Integer) → Integer\)
function product(x, y) {
return x * y
}
これは高階関数を使えば一引数の関数だけで実装可能になる
function product(x) {
return function(y) {
return x * y
}
}
product(2)(3) //=> 6
これを関数のカリー化と言う
function product(x) {
return function(y) {
return x * y
}
}
まず外側のfunctionに注目
\(Integer\) である x を受け取り関数を返している
\(Integer → (T → S)\)という型になる(\(T\), \(S\)は型変数)
返している関数の型は\(Integer\) yを受け取り\(Integer\)を返り値にしているので\(Integer → Integer\)である
以上より関数productの型は\(Integer → (Integer → Integer)\)である
右結合にするのが一般的である
すなわち
\(Integer → Integer → Integer\)
は
\(Integer → (Integer → Integer)\)
である
同様に \(T_1 → T_2 → T_3 → T_4\) は \(T_1 → (T_2 → (T_3 → T_4))\) である
\(T_1 → T_2 → T_3 → T_4\)
型が\(T_1, T_2, T_3\)の3つの引数を受け取り型が\(T_4\)の戻り値を返す関数の型
と読める
function(x, y, z) {
return x + y + z
}
function(x) {
return function(y) {
return function(z) {
return x + y + z
}
}
}
\((T_1 → T_2) → (T_3 → T_4)\)
型が\(T1 → T2\)となる関数を引数に受け取り型が\(T_3→T_4\)となる関数を戻り値とする関数の型
と読める
function (f) {
return function(x) { /* ... */ }
}
オブジェクト指向で言う所のインタフェイスみたいなもの
Haskellでは\(Integer\)型は\(Ord\)という型クラスのインスタンスである
\(Ord\)型クラスに属する型に属する値はOrdinaryでなければならない(順序を持ってなければならない)
\(Ord\)型クラスに属する\(Integer\)型の値1, 2, 3...は順序を持っている
... < 0 < 1 < 2 < 3 < 4 < ...
\(Ord\)型クラスは\(Eq\)型クラスを継承している
\(Eq\)型クラスは属する型の値が同値かどうかが確認出来なければならない(=の演算が出来なければならない)
※代入ではない
\(Integer\)と\(Floating\)型クラスは\(Num\)型クラスを継承している
などがある
型クラスは型コンストラクタを持つ
型コンストラクタは型を引数に取ることがある
Array型クラスなどはIntegerやFloatingなどの型を取りIntegerやFloatingの配列型となる
C++のtemplateを知ってる人は想像すると分かりやすいかも
OptionalもMaybeも型クラスである
Optional(Int)型はInt型の値か又はnilを持つ
Maybe IntegerはInteger型の値か又はNothingを持つ
そういうものを扱う方法を抽象化することが出来る
Functor
\((a → b) → (f a → f b)\)
Applicative
\(f (a → b) → f a → f b\)
Monad
\(m a → (a → b) → m b\)