第12回
関数型言語
1. 関数型言語
2. 型理論
型システム入門 −プログラミング言語と型の理論 −
Benjamin C. Pierce (著), 住井 英二郎 (監訳)
ISBN: 9784274069116
画像は https://www.amazon.co.jp/dp/4274069117 より引用
1
12-1関数型言語
2
プログラミング パラダイム
プログラミング言語が備える概念の体系をパラダイムと呼ぶ
● 手続き型言語
計算機にさせる処理を、逐次的に記述していく方法。関数定義は、定型的な処理を
まとめるためのプロシージャとしての役割を果たす
● 関数型言語
プログラム中の演算をはじめ、条件式、関数などをすべて評価できる対象としてみ
なす方法。関数そのものも値としてみなすことができる
3
副作用 (Side Effect)
プログラムを実行した結果、外部の環境に変化を与えることを副作用という
プログラムの実行中に、グローバル変数を更新するなどが最たる例
プログラム入力 出力
環境
4
参照透過性 (Referential Transparency)
プログラムが参照に対して透過的 (意識しないこと) である性質を参照透過性という。同
一の入力をしたら、必ず同一の出力が返ってくる (純粋である)
環境 (プログラムの外側に存在するデータ) を読み書きするプログラムは参照透過的で
はない。副作用がないことは必要条件。参照透過性を持つプログラムは決定的
(Deterministic) に動作する
プログラム入力 出力
環境
5
関数型言語 OCaml の紹介
フランスの INRIA で開発された ML 系の言語
値の束縛: let x = 100 in x + 10
関数定義: let dbl x = x * 2 in dbl 10
再帰関数の定義:
let rec fib x =
if x <= 1 then 1
else fib (x - 1) + fib (x - 2)
http://ocaml.org/docs/logos.html より引用
6
不変なデータ構造
OCaml を始めとする多くの関数型言語では、参照透過性を確保するために、値を代入
するという処理が存在しないことが多い。代わりに、同一変数名に対して再束縛すると
いう概念になる。不変 (immutable) なデータであるという
...
let x = 10 in
(* use x *)
...
let x = 20 in
(* use x *)
x : int = 10
x : int = 10
x : int = 20
∅
7
リスト
不変なデータ構造を基本的に扱う OCaml では、リストが好んで良く用いられる
● リストの作成
● リストの要素の追加
● リストの接続
● 先頭要素の取得
● 残りの取得
1 :: [2;3]
List.hd l
[a;b;c]
List.tl l
[1;2] @ [3;4]
例:
8
バリアント型とタプル
バリアント型: 1 つの型で、ラベル (と値) のいずれかを選択する値を保持できる
タプル型: 1 つの型で、複数の異なる型の値を同時に保持できる
type literal =
| Int of int
| Boolean of bool
Int 10 : literal
type 'a optional =
| Some of 'a
| None
Some 10 : int optional
(10, "Hello") : int * string
9
マッチング
OCaml の優れた機能のひとつとしてパターン マッチングが存在する
値を、特定の型や形式でマッチさせることができ、かつ変数への束縛もすることができる
match operation with
| Add (x, y) -> ...
| Negate x -> ...
| _ -> ...
let Add (x, y) = ... in
x + y
パターンマッチングの例 :
10
末尾再帰
関数型言語にはループなどの繰り返し構造が存在しないことが多いので、代わりに再帰
呼び出しを用いる。通常の関数呼び出しはスタックを消費してしまうので、関数の末尾で
呼ぶことでスタック消費を抑える
let sum =
let rec add total =
function
| [] -> total
| head :: tail -> add (head + total) tail
in
add 0;;
末尾再帰の例:
11
[課題] 末尾再帰への変換
次のプログラムは末尾再帰になっていない。これを末尾再帰に書き直せ
let rec rev = function
| [] -> []
| a :: b -> (rev b) @ [a]
12
高階関数
関数型言語では、関数も値としてみなすことができるので、関数の引数や戻り値に関数
を用いることができる
let rec combine f g x = g (f x)
combine: ('a -> 'b) -> ('b -> 'c) -> 'a -> 'c
let rec fold_left (f:'a->'b->'a) (acc:'a) (l:'b list):'a =
match l with
| [] -> acc
| x :: xs -> fold_left f (f acc x) xs
高階関数の例:
13
12-2型理論
14
型とは (再び)
型とは、計算機上に扱うデータ構造を決定したり、プログラムする上での扱いを制限した
りするための枠組み。たとえば、整数であれば、整数としてのデータ構造で配置され、ま
た整数演算などが可能になる
● 整数型: 加減乗除、剰余などの演算
● 文字列: 文字列の結合
● 日時, 時間: 加算
たとえばプログラム上の関数は、引数に特定の型のデータを受け取ることを予期し、特
定の型で結果を戻す
15
型付けと型推論
関数や変数に値を束縛する際、その型を定める必要がある。これを型付け (Typing) と
いう
言語によっては型の略記を許すこともあり、コンパイラが関数や変数の型を推論 (Type
inference) しなければならないことがある
let add x y =
x + y
let x = 10
add : int → int
x : int
16
型付けのタイミング
計算機が値や変数に型付けをするタイミングは 2 種類ある
● 静的な型付け
プログラムをコンパイルする時点で、プログラム全体を通して一貫性のある型付け
を行い、その途中で関数や変数の値の束縛に矛盾が生じるならばエラーとする方
式
● 動的な型付け
コンパイル時点で変数には特定の型を定めることをせず、実行時に値とともに型情
報を紐付けて受け渡しする方式。値に対する操作は実行時になって初めて正当か
どうか検証される
17
型付けの強さ
プログラミング言語がどの程度まで型を強制するかによって、強さという概念が存在する
● 強い型付け
OCaml のように型情報に違反する操作を記述する文法が原則として存在しない言
語 (Obj.magic が唯一の例外)
● 弱い片付け
型検査が行われるが、キャスト演算子やポインタなどで型情報をプログラマの意思
で変更したり、型情報を無視したデータの読み書きができる言語
18
多相型 (Polymorphic Type)
上記の定義において rev の型はどうなっているか?
rev [1;2;3] = [3;2;1] なら rev は int list -> int list として動くが、
文字列のリストを渡しても構わない
let rec rev = function
| [] -> []
| a :: b -> (rev b) @ [a]
rev : 'a list -> 'a list = <fun>
19
(参考) オブジェクト指向プログラミング (OOP)
● カプセル化 (Encapsulation)
機能単位においてデータを抽象化し、具体的な操作や内容を秘匿する。特定の内部情報が破
損するのも防ぐことができる
● 継承 (Inheritance)
類似する機能をもつ複数のオブジェクトについて、共通部分とそれ以外の部分に分け、共通部
分を基底としながら、残りの部分の機能単位がそれを拡張できるようにすること
● ポリモーフィズム (Polymorphism)
異なるオブジェクトどうしにあっても、共通の機能を提供する場合には、共通のインタフェースを
通じて提供することができ、機能の利用側はその差を意識する必要がないこと
20
ダック タイピング
ある鳥が鴨のように見え、鴨のように泳ぎ、鴨のように鳴くならば、それはたぶん鴨である。
— https://ja.wikipedia.org/wiki/ダック・テスト より引用
おもに動的型付けのシステムにおいて、あるオブジェクトの型情報において特定の型を
継承していなかったとしても、利用する側が期待するインタフェースを備えているならば
同一視して、それを利用できるようにしてしまうこと
C# では dynamic というキーワードで行うことができる
var l = new List<int> {...};
l.Sort();
dynamic myList = ...;
myList.Sort();
Sort インタフェースがなくても、関数
名が同じであれば実行できる
21
第12回 まとめ
1. 関数型言語
● プログラミング パラダイム
● 副作用 / 参照透過性 / 不変性
● OCaml の紹介
● バリアント型 / タプル / マッチング / 末尾再帰
2. 型理論
● 型付け / 型推論
● 静的型付け / 動的型付け
● 多相型 / ダック タイピング
22

[Basic 12] 関数型言語 / 型理論