プログラミング言語standard ml — introduction to …...mlの教科書 our lecture will...

180
プログラミング Standard ML — Introduction to Standard ML — http://www.pllab.riec.tohoku.ac.jp/ ohori/

Upload: others

Post on 21-Jan-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

プログラミング言語Standard ML入門— Introduction to Standard ML —

大堀 淳

http://www.pllab.riec.tohoku.ac.jp/∼ohori/

& %

Page 2: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

MLとはどんな言語?

幾つかの答え

• LCFシステムのメタ言語(Meta Language).

•現在では汎用のプログラミング言語.

•関数型言語の一つ.•静的に型付けられた言語.

•堅牢な理論的基礎を持つ言語.

1& %

Page 3: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

補足:Metaとは?

•「後に」の意味.もともとは単なる位置の概念•アリストテレスのmetaphysica(形而上学)により「超越」との解釈が加わる

–もともとはmetaphysica(ta meta ta physika)「自然学(physica)の後に置かれた書」の意味.

–その内容から,metaは自然学を越えた,との意味となる.

•カントの超越論的観念論(純粋理性批判)によって,自然学の「超越」が,「認識の地平を越える」との解釈に洗練される.

•言語に関する文脈では,メタとは,言語活動を分析反省する立場.メタ言語:(対象)言語活動を記述するための言語.

•例:Cで書かれたJAVAのコンパイラでは,CはJAVAを翻訳するためのメタ言語.

2& %

Page 4: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

MLの特徴は?

幾つかの重要な特徴:

•ユーザ定義のデータ型•パターンマッチング•自動的なメモリー割り当て(ごみ集め付きヒープ管理)•第1級のデータとしての関数

•言語と一体となったモジュールシステム•多相型言語•自動型推論機構を装備

MLはハッカー1 のためのクールなプログラミング言語.

1 A person with an enthusiasm for programming or using computers as an end in itself.

3& %

Page 5: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

MLの歴史

• 60’s: LCF システムのメタ言語として誕生

• 1972: Milnerの多相型型推論アルゴリズム.

• early 80’S: CardelliによるFAMを使った実装

• 80’s: “Polymorphism”誌へのStandard MLの提案

• 80’s: Standard MLの開発(Edinburgh大)

• 80’s: Camlの開発(INRIA)

• late 80’s: LeroyによるCaml-lightの開発(INRIA)

• early 90’s: AppelとMacQueenによるStandard ML of New Jerseyの開発(Bell研/Princeton)

• 90’s: LeroyによるObjective Camlの開発(INRIA)

• 2008: SML#を開発(東北大学電気通信研究所)

4& %

Page 6: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

現在のMLの主な方言

1. Standard ML「公式」版.その仕様が以下の本として出版されている.

R. Milner, M. Tofte, R. Harper, and D. MacQueenThe Definition of Standard ML (revised), MIT Press, 1997.

2. Objective Camlフランスの方言.フランス INRIA研究所で開発.言語の名前であるとともに,処理系の名前でもある.高性能な処理系だが,上記の仕様との互換性はない.

3. SML]東北大学電気通信研究所堀研究室で開発中.alpha版をリリースずみ.Standard MLの拡張版;The Definition of Standard MLと完全な上位互換性.

5& %

Page 7: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

MLの教科書

Our lecture will roughly be based on

プログラミング言語Standard ML入門,大堀 淳,共立出版.

Other resources

• L. Paulson, ”ML for the Working Programmer, 2nd Edition”,Cambridge University Press, 1996.(多くのトピックが扱われた良書)

• R. Harper, ”Programming in Standard ML”.http://www.cs.cmu.edu/People/rwh/introsml/(on-lineで入手できる.)

• M. Tofte, ”Four Lectures on Standard ML” (SML’90)ftp://ftp.diku.dk/pub/diku/users/tofte/FourLectures/sml/(短いがよく書けたチュートリアル)

6& %

Page 8: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

MLのFAQ,或は,MLに関する種々の偏見・誤解

• Q. MLは理論に基づく言語なので,学ぶのが難しいのでは?A.実際は逆です.

堅牢な基礎の基に良く設計された機械は,理解しやすく操作も簡単.

MLプログラミングをマスターするには,いくつかの数少ない原理を身を理解すればよい.

–式とその評価,

–関数 (再起関数,第1級のデータとしての関数),

–型,

–データ型とパターンマッチング.

これらMLの構造は,手続き型言語より遥かに単純.7& %

Page 9: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

• Q. そうはいっても,関数型プログラムはむずかしいのでは?A.いえ,手続き型プログラムより単純かつ自然です.例:

0! = 1

n! = n×!(n − 1)

in ML,fun f 0 = 1

| f n = n * f (n - 1)

in Cf(int n){

int r;

while (n != 0) {r = r * n;

n = n - 1; }return(n);}

一般にMLのコードはより簡単でエラーが少ない.8& %

Page 10: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

• Q. コンパイルエラーが多く,開発の能率が悪いのでは?A.いえ,コンパイルエラーのおかげで開発効率が高いのです.エラーを含むコードの例:in ML,fun f L nil = L

| f L (h::t) =

f (h@L) t

Type Error:

circularity

’Z list -> ’Z list

’Z -> ’Z list

in Lisp(defun f (l1 l2)

(if (null l1) l2

(cons (cdr l1)

(f (car l1) l2))))

f

MLはこのように総ての型エラーをコンパイル時に報告する.これにより,MLのプログラム開発効率は他を圧倒して高い.

9& %

Page 11: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

• Q. MLで書かれたプログラムは遅いのでは?

• MLは所詮研究者のおもちゃでしょう.

...

研究者/ハッカーとして,実際のソフトウエア開発現場で使い物になるML言語を開発し,この2つに応えたい ....

10& %

Page 12: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

以降の内容

1. MLを使ってみよう

2. 値の束縛と関数定義

3. 再帰的関数と高階の関数

4. 静的型システム

5. リスト

11& %

Page 13: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

参考資料

さらに興味のある方は,本特別講義の参考資料のページから

⇒「MLに関する種々の情報」(参考)

⇒「プログラミング言語Standdard ML入門に準拠した解説スライド」(英語版)

を参照.本資料の内容以外に,以下のような内容が含まれます.

6. MLの組み込みデータ型

7. 再帰的データ型の定義

8. 手続き型プログラミングの機能

9. モジュールシステム

10.基本ライブラリ

11.プログラミングプロジェクト

12& %

Page 14: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

1. MLを使ってみよう

13& %

Page 15: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

MLをインストール

1.SML of NJのホームページ

http://www.smlnj.org/software.html

に行き,公式リリース版である110.0.7-4版をダウンロード.

2.SML#のホームページ

http://www.pllab.riec.tohoku.ac.jp/smlsharp/ja/

に行き,「ダウンロード」のページからSML]アルファリ版をダウンロード

14& %

Page 16: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

MLの起動と使い方

対話型モードの実行を開始

% smlsharp (SML]システムの起動)restoring static environment... (起動情報)# (入力プロンプト)

この後,以下のような対話をしながらプログラムする.

1. ユーザによるプログラムの入力,

2. システムによるプログラムのコンパイルと実行,

3. システムによる結果の表示.

セッションの終了

•対話型セッションの終了にはトップレベルで^Dを入力する.

•プログラムを中断するには^Cを入力する

15& %

Page 17: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

式とその評価

関数型言語の基本原理

プログラムは一つの式.式の評価がプログラムの実行.

対話型セッションで以下のように式を入力:

# expr ; (an expression)val it = value : type (the result)

ここで

• “;” はコンパイル単位の終了記号.

• value はプログラムの実行結果を表す式の値.

• typeはMLコンパイラが推論した式の型.

• val it は,システムが結果に“it”という名前を付け記録していることを表す.

16& %

Page 18: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

原子式

MLでは,“hello world”プログラムは単に以下のように書けばよい:

% smlsharp

# "Hi, there!";

val it = ”Hi, there!” : string

MLでは簡単なプログラムは実際に簡単!このプログラムをCのプログラムと比較してみよ.

注意:

• ”Hi, there!”は一つの式.従って完全なプログラム.

•これは,原子式(定数リテラル式)の例.•原子式の評価結果はそれ自身(の計算機での表現).• MLは式の型を推論する.この場合,stringが推論されている.

17& %

Page 19: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

幾つかの原子式の例:

# 21;

val it = 21 : int# 3.14;

val it = 3.14 : real# 1E2;

val it = 100.0 : real# true;

# true;

val it = true : bool# false;

val it = false : bool# #"A";

val it = #”A” : char

ここで

• int : 整数型

• real : 浮動小数点数の型

• bool : 真理値型

• char : 文字データ型

18& %

Page 20: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

組み込み演算式

簡単な算術式の例

# ~2;

val it = ˜2 : int# 3 + ~2;

val it = 1 : int# 22 - (23 mod 3);

val it = 20 : int# 3.14 * 6.0 * 6.0 * (60.0/360.0);

val it = 18.84 : real

• ~nは負の数の表現.-はマイナス1倍する演算.

• modは剰余を求める演算子

19& %

Page 21: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

式はいくら長くてもよい.

# 2 * 4 div (5 - 3)

> * 3 + (10 - 7) + 6;

val it = 21 : int

最初の > は継続行のプロンプト.

20& %

Page 22: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

条件文と真理値を持つ式

MLではプログラムは一つの式(基本原理(1)).よって,

条件分岐するプログラムもやはり1つの式

# if true then 1 else 2;

val it = 1 : int# if false then 1 else 2;

val it = 2 : int

ここでtrueとfalseはそれぞれ真と偽を表すbool型の定数.

注:

• if E1 then E2 else E3は式であり,従って値をもつ.

• E1は任意の真理型の式でよい.

21& %

Page 23: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

型付き言語の基本原理:

式は,型が正しい限りどのように組み合わせてもよい.

したがって,以下のようなことが可能

# (7 mod 2) = 2;

val it = false : bool# (7 mod 2) = (if false then 1 else 2);

val it = false : bool# if (7 mod 2) = 0 then 7 else 7 - 1;

val it = 6 : int# 6 * 10;

val it = 60 : int# (if (7 mod 2) = 0 then 7 else 7 - 1) * 10;

val it = 60 : int

22& %

Page 24: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

“it”式

システムはitという式に最後に評価された式の値を保持.

# 31;

val it = 31 : int# it;

val it = 31 : int# it + 1;

val it = 32 : int# it;

val it = 32 : int

23& %

Page 25: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

文字と文字列

# if #"A" > #"a" then ord #"A" else ord #"a";

val it = 97 : int# chr 97;

val it = #”a” : char# str it;

val it = ”a” : string# "SML" > "Lisp" ;

val it = true : bool# "Standard " ^ "ML";

val it = ”Standard ML” : string

• ord e は文字eのASCIIコードを返す.

• chr e は整数eに対応する文字を返す.

24& %

Page 26: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

ファイルからのプログラムの読み込み

ファイルに格納されたプログラムを実行するためには,以下の特殊構文を用いる.

use "file" ;

システムはこの文を以下のように処理する.

1. ファイルを開く.

2. “;”を区切りとして式を読み込み,コンパイル,実行する.

3. ファイルを閉じる.

4. トップレベルに戻る.

25& %

Page 27: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

構文エラーと型エラー

他の言語同様,構文に誤りがあればエラーを報告する.

# (2 +2] + 4);

stdIn:1.7 Error: syntax error found at RBRACKET

さらに,型の不整合があれば型エラーを報告する.

# 33 + "cat";

stdIn:21.1-21.11 Error: operator and operand don’t agree [literal]operator domain: int * intoperand: int * stringin expression:

33 + ”cat”

26& %

Page 28: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

型のキャストは存在しない

# 10 * 3.14;

stdIn:2.1-2.10 Error: operator and operand don’t agree [literal]operator domain: int * intoperand: int * realin expression:

10 * 3.14

必要なら型の変換を行う.

# real 10;

val it = 10.0 : real# it * 3.14;

val it = 31.4 : real

27& %

Page 29: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

練習問題(1)

1. SML]をインストールし上記のような対話が可能であることを確認せよ.

2. 以下の結果を予想せよい.

1 44;

2 it mod 3;

3 44 - it;

4 (it mod 3) = 0;

5 if it then "Boring" else "Strange";

予想結果を,SML]で確認せよ.

3. 変数Xに英字の大文字が定義されているとする.ASCIIコードはAからZまでこの順に並んでいる.小文字に付いても同様であ

28& %

Page 30: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

る.この事実を使い,Xに束縛された英字の小文字が得られる式を書け.

4. ASCIIコードでは,英字大文字と英字小文字は連続していない.これら集合の間にある文字数を求める式を書け.その結果を使って,英字の大文字と小文字の間にある文字を連結して得られる文字列を求める式を書け.

29& %

Page 31: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

2. 値の束縛と関数定義

30& %

Page 32: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

値の束縛

プログラム開発の第一歩は式に名前をつけ,その後の式の中で使用すること.

val name = exp ;

これによってnameがexprに束縛される.environment.

# val OneMile = 1.6093;

val OneMile = 1.6093 : real# OneMile;

val it = 1.6093 : real# 100.0 / OneMile;

val it = 62.1388181197 : real

31& %

Page 33: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

変数の型を宣言する必要はない.

# val OneMile = 1.609;

val OneMile = 1.609 : real# val OneMile = 1609;

val OneMile = 1609 : int# OneMile * 55;

val it = 88495

定義されていない変数の参照は型エラーとなる.

# onemile * 55;

stdIn:22.1-22.8 Error: unbound variable or constructor: onemile

32& %

Page 34: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

Identifiers

変数として使用可能な名前は,以下2種類

1. アルファベット名大文字,小文字, または#”’” ではじまり,文字, 数字, #”’”,#” ” だけからなる名前.ただし#"’"から始まる名前は型変数としてのみ使用可能.

2. 記号名以下の記号からなる名前.

! % & $ # + - / : < = > ? @

\ ~ ‘ ^ | *

33& %

Page 35: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

予約語

abstype and andalso as case datatype do else end

eqtype exception fn fun functor handle if in

include infix infixr let local nonfix of op open

orelse raise rec sharing sig signature struct

structure then type val where while with withtype

( ) [ [ { } , : :> ; ... | = => ->

#

34& %

Page 36: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

関数定義

関数は以下の fun構文で定義する:

fun f p = body ;

ここで

• fは関数の名前,

• pは仮引数,

• bodyは関数本体.

これによって,引数pを受け取り,bodyの値を計算する関数が定義される.

35& %

Page 37: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

簡単な例:

# fun double x = x * 2;

val double = fn : int -> int

ここで

• val double = fnは変数doubleが関数の値に束縛されたことを示す.

• int -> intはこの関数が,整数を引数として取り整数を返す関数であることを表す型.

関数は以下のように使用する.

# double 1;

val it = 2 : int

36& %

Page 38: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

関数適用

型に関する規則:

型τ1 -> τ2を持つ関数fは,型τ1をもつ式Eに適用することができ,結果は型τ2である.

この条件を簡潔に以下のように書ける.

f : τ1 -> τ2 E : τ1f E : τ2

型付き言語の基本原理を思いだそう.

式は,型が正しい限り自由に組み合わせることができる.

そこで,Eはどのような式でもよく,また,f Eはτ1型が許されるところにならどこにでも使用できる.

37& %

Page 39: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

# double (if true then 2 else 3);

val it = 4 : int# double 3 + 1;

val it = 7 : int# double (double 2) + 3;

val it = 11 : int

重要な表記上の約束:

関数適用E1 E2は左結合し,最も結合力が強い.

たとえばdouble 3 + 1は(double 3) + 1の意味である.

38& %

Page 40: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

簡単なパターンを用いた関数定義

# fun f (x,y) = x * 2 + y;

val f = fn : int * int -> int# f (2,3);

val it = 7 : int

ここで,

• (E1,. . .,En)は組を表す式,

• τ1 * · · · * τnは組型.

•関数構成子 -> は他の型構成子より結合力が弱い.従って,int *

int -> int は (int * int) -> int と解釈される.

39& %

Page 41: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

関数的用の型推論規則

E1 : τ1 · · · En : τn(E1,. . .,En) : τ1 * · · · * τn

そこで,以下のように任意の組を構成できる.

# ("Oleo",("Kenny","Drew"),1975);

val it = ("Oleo",("Kenny","Drew"),1975): string * (string * string) * int

40& %

Page 42: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

3. 再帰的関数と高階の関数

41& %

Page 43: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

再帰的関数

関数定義構文

fun f p = body

のbodyではこの構文で定義している関数f自身を使用することができる.

簡単な例: 階乗を計算する関数

the definition

0! = 1

n! = n × (n − 1)!

ML codefun f n =

if n = 0 then 1

else n * f (n - 1)

多くの問題は再帰的に考えることによって解くことができる.

42& %

Page 44: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

再帰的関数の設計:

0! = 1

n! = n × (n − 1)!

1. 自明な基底のケースを書く.if n = 0 then 1

2. 複雑なケースを部分問題に分解し,部分問題を今定義している関数自身を使って解く.f (n - 1)

3. 結果を合成し,最終結果を作成.n * f (n - 1)

43& %

Page 45: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

再帰的関数の分析:

fun f n =

if n = 0 then 1

else n * f (n - 1)

1. fが目的とする結果を返すと仮定する.f n is n!

2. この仮定の下でbodyが正しいことを確認する.f 0 is 0!.仮定より,f (n - 1)は(n − 1)!を計算するしたがってf nは n!. そこで,この定義の本体は正しい.

3. 以上が成功したら,fは目的とする結果を返す関数であると証明される

44& %

Page 46: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

例:Fibonacci数列:

F0 = 1

F1 = 1

Fn = Fn−2 + Fn−1 (n ≥ 2)

Fibonacci数を計算する関数.

fun fib n = if n = 0 then 1

else if n = 1 then 1

else fib (n - 1) + fib (n - 2)

45& %

Page 47: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

末尾再起関数

以下の関数定義を再考してみる.

fun f n =

if n = 0 then 1

else n * f (n - 1)

この関数はO(n)のスタックスペースを使用.しかし,Cで書けば2,3の変数を使うループですむ.

MLはやはり非効率的?

この答えは自明なもの.

効率的なMLプログラムは効率的で,非効率なMLプログラムは非効率.

46& %

Page 48: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

再帰的関数定義fun f p = bodyに於て,fがbodyの中で末尾(tailcalls positions)にしか現れないとき,この関数を末尾再起(tailrecursive)関数と呼ぶ.

Tの中で [ ]は末尾:

T := [ ] | if E then T else T | (E; · · ·; T)

| let decs in T end

| case e of p1 => T | · · · | pn => T

末尾呼び出しの例:

• f e

• if e1 then f e2 else f e3

• let decls in f e end

末尾再起関数はスタックを使用せず,従ってより効率がよい.

47& %

Page 49: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

末尾再起に変更したfact関数:

fun fact (n, a) = if n = 0 then a

else fact (n - 1, n * a);

val fact = fn : int * int -> int

fun factorial n = fact (n,1);

val factorial = fn : int -> int

factは factorialの補助関数.

48& %

Page 50: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

Let式

letで局所的な定義を導入できる.

let

sequence of val or fun definitionsin

expend

簡単な例:

let

val x = 1

in

x + 3

end;

val it = 4 : int

49& %

Page 51: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

MLでは関数は通常このように let式を使って定義される.

- fun factorial n =

let

fun fact n a = if n = 0 then a

else fact (n - 1) (n * a)

in

fact n 1

end;

val factorial = fn : int -> int

50& %

Page 52: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

let decl in exp endに関する注意:

•もれも式.•この式の型はexpの型.

# let

val pi = 3.141592

fun f r = 2.0 * pi * r

in

f 10.0

end * 10.0;

val it = 628.3184 : real

51& %

Page 53: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

Local構文

以下のlocal構文も局所的な定義に使用できる.

local

declList1in

declList2end

• declList1はdeclList2の中でのみ有効

• declList2のみがこの構文の後有効.

52& %

Page 54: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

# local

fun fact n a = if n = 0 then a

else fact (n - 1) (n*a)

in

fun factorial n = fact n 1

end;

val factorial = fn : int -> int# fact;

stdIn:10.1-10.4 Error: unbound variable or constructor fact

53& %

Page 55: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

相互再帰関数

互いに他の関数を利用し合う2つ以上の関数も定義できる.これらを相互再帰的関数と呼ぶ.

相互再帰的な関数の簡単な例として,ある年の預金の利率がその年の初めの預金残高によって決まる場合の,残高と利率を計算する問題を考えてみよう.

• Anx n年目の年末の預金残高

• Inx x万円を預けたときの,n年目の利率

とすると以下の関係がある.

54& %

Page 56: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

Inx = F (An−1

x ) (n ≥ 1)

Anx =

x (n = 0)

An−1x × (1.0 + In

x ) (n ≥ 1)

これらは,キーワード and を用いて以下のように相互再帰的関数として定義できる.

# fun I(x,n) = F(A(x,n - 1))

and A(x,n) = if n = 0 then x

else A(x,n-1)*(1.0+I(x,n));

val I = fn : real * int -> realval A = fn : real * int -> real

55& %

Page 57: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

高階の関数

高階言語の基本原理

関数は式で表現される値(第1級のデータ.)(1) 関数を返す関数2引数関数は以下のように書ける.# fun Power(m,n) = if m = 0 then 1

else n * Power(m - 1,n);

val Power = fn : int * int -> int# Power(3,2);

val it = 8 : int

しかしMLでは,以下のような別の書き方も可能.# fun power m n = if m = 0 then 1

else n * power (m - 1) n;

val power = fn : int -> int -> int

56& %

Page 58: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

powerは,mを受け取り「nを受け取りmnを返す関数」を返す関数.

たとえば,以下のように使用できる.

# val cube = power 3;

val cube = fn : int -> int# cube 2;

val it = 8 : int

注意:

•関数適用は左結合するpower (m - 1) nは(power (m - 1)) nの意味.

• ->は右結合するint -> int -> intは int -> (int -> int)の意味

57& %

Page 59: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

(2) 関数を受け取る関数この機能を理解するために,以下の関数を考えてみよう:

# fun sumOfCube n = if n = 1 then cube 1

else cube n + sumOfCube (n - 1);

val sumOfCube = fn : int -> int# sumOfCube 3;

val it = 36 : int

sumOfCubeは以下のような計算パターンの特殊な場合である.n∑

k=1f (k) = f (1) + f (2) + · · · + f (n)

58& %

Page 60: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

MLでは,このような計算のパターンを直接関数として定義できる.

# fun summation f n = if n = 1 then f 1

else f n + summation f (n - 1);

val summation = fn : (int -> int) -> int -> int

注:

• (int -> int) -> int -> int は(int -> int) -> (int -> int).

•この型は,summationが

–型 int -> intの値を受け取り– int -> intの値を返す

関数であることを意味している.

すまり,summationは関数を受け取り関数を返す関数.

59& %

Page 61: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

「高階言語の基本原理」を「型付き言語の基本原理」と組み合わせれば,以下のように使用可能であることが分かる.

# val newSumOfCube = summation cube;

val newSumOfCube = fn : int -> int# newSumOfCube 3;

val it = 36 : int

さらに,

# val sumOfSquare = summation (power 2);

val sumOfSquare = fn : int -> int# sumOfSquare 3;

val it = 14# summation (power 4) 3;

val it = 98 : int

60& %

Page 62: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

関数式

関数は値であるから,当然式で表現できる.

fn p => body

これは,pを引数として受け取りbodyの値を計算する名前のない関数.

# fn x => x + 1;

val it = fn : int -> int# (fn x => x + 1) 3 * 10;

val it = 40 : int

61& %

Page 63: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

この式を使えば,実行時に関数を作り出すようなプログラムを定義できる.

fun f n m = (fib n) mod m = 0;

この関数は各mに対してfib mを計算するため,効率がわるい.

val g = f 35;

(g 1,g 2,g 3,g 4,g 5);

はfib 35を5回計算すう r.

62& %

Page 64: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

関数式をつかいこのfib 35の計算をくくり出すことが可能.

fun f n = let val a = (fib n)

in fn m => a mod m = 0

end

この関数は,以下の計算を行う.

1. nを受け取る

2. fib nを計算し結果をmに束縛,

3. このmを使い,関数fn m => a mod m = 0を生成し返す.

この定義を使えば,例えば

val g = f 35;

(g 1,g 2,g 3,g 4,g 5);

などでもfib 35の計算は1回しか実行されない.

63& %

Page 65: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

静的スコープ規則

名前の使い方の基本法則:

1. 名前の定義には有効範囲があり,

2. 新しい名前の定義は,その有効範囲で,以前の定義を隠す.

この法則は,人間が使用するおよそすべての言語にあてはまる.

簡単な例:

# let val x = 3 in (fn x => x + 1) x end;

val it = 4 : int

名前が定義される構文:

• val 定義• fun 定義• fn x => e 式

64& %

Page 66: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

val 定義

val x1 = exp1and x2 = exp2

...

and xn = expn ;

x1, . . . , xnのスコープはこの定義に続く部分

val x = 1

val y = x + 1

val x = y + 1

and y = x + 1

この構文によりxは3にyは2に束縛される.

65& %

Page 67: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

関数定義

fun f1 p11 · · · p1

k1= exp1

and f2 p21 · · · p2

k2= exp2

...

and fn pn1 · · · pn

kn= expn ;

f1, . . . , fnのスコープ:

• exp1, . . . , expn

•この定義に続く部分

66& %

Page 68: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

注:

新しい名前は古い名前を隠すのみ.古い定義を変更するわけではない(通常の言語でもあたりまえ.).

# val x = 10;

val x = 10 : int# val y = x * 2;

val y = 20 : int# val x = 20;

val x = 20 : int# y;

val it = 20 : int

67& %

Page 69: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

関数定義でも同様.

# val x = 10;

val x = 10 : int# val y = 20;

val y = 20 : int# fun f x = x + y;

val f = fn : int -> int# f 3;

val it = 23 : int# val y = 99;

val y = 99 : int# f 3;

val it = 23 : int

68& %

Page 70: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

2項演算子

MLでは, 演算子は二引数関数にすぎない.

e1 op e2

はop(e1,e2)

の糖衣構文.この糖衣構文を使いたい場合,以下の宣言を行う.• infix n id1 · · · idn : 結合力nの左結合演算子の導入.

• infixr n id1 · · · idn : 結合力nの右結合演算子の導入.

システムではあらかじめ以下の宣言をしている.infix 7 * /

infix 6 + -

69& %

Page 71: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

ユーザも自由に定義可能.

# infix 8 Power;

infix 8 Power# 2 Power 3 + 10;

val it = 19 : int

この宣言を一時的に無効にするにはop id構文を用いる.

# Power;

stdIn:4.1 Error: nonfix identifier required# op Power;

val it = fn : int * int -> int# op Power (2,3);

val it = 9 : int

70& %

Page 72: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

練習問題 (2)

1. 以下のそれぞれに対して,再帰的な漸化式を書き,それをもとに,関数を定義せよ.

(1) Sn = 1 + 2 + · · · + n

(2) Sn = 1 + (1 + 2) + (1 + 2 + 3) + · · · + (1 + 2 + · · · + n)

2. 上記の各関数の末尾再帰版を定義せよ.

3. 2 × 2の行列a bc d

を(a, b, c, d)と表現することにする.行列Aと

自然数nを受け取りAnを計算する関数matrixPower(n,A)を定義せよ.

4. Fibonacci数の定義から以下の等式が得られる.

Fn = Fn

Fn+1 = Fn−1 + Fn

71& %

Page 73: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

さらに,

Gn =

Fn

Fn+1

と定義すると

Gn =

0 11 1

Gn−1

したがって,

Gn =

Fn

Fn+1

=

0 11 1

0 11 1

· · ·0 11 1

︸ ︷︷ ︸

n times

01

となる.そこで,もしA =

0 11 1

なら,

Gn = An01

72& %

Page 74: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

である.この性質を使って,Fnを計算する関数をmatrixPower

を使って定義せよ.

5. summationを末尾再帰関数として定義せよ.

6. 以下の各関数を定義せよ.using summation.

(1) f (x) = 1 + 2 + · · · + n

(2) f (n) = 1 + 22 + 32 + · · · + n2

(3) f (n) = 1 + (1 + 2) + (1 + 2 + 3) + · · · + (1 + 2 + · · · + n)

7. 型int -> realをもつ関数fに対して∑nk=1 f (k)を計算する後悔

関数

summation’ : (int -> real) -> int -> real

を定義せよ.

8. f (x)を実数上の関数とする.∫ ba f (x)dx

73& %

Page 75: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

は,ある程度大きなnに対して,以下のように近似できる.n∑

k=1

fa +

k(b − a)

n

×b − a

n

f,n,a,bを受け取り,上記の近似値を計算する関数integral

を定義せよ.必用なら,int型の値をreal型に変換する関数real : int ->

realを使用せよ.

9. summationは以下のより一般的な計算パターンの特殊な場合である.

Λnk=1(h, f, z) = h(f (n), · · · , h(f (1), z) · · ·)

例えば.∑nk=1 f (k)はΛn

k=1(+, f, 0)と定義できる.Λn

k=1(h, z, f )を計算する高階関数

accumulate h z f n

74& %

Page 76: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

を定義せよ.

10.accumulateを使ってsummationを定義せよ.

11.accumulateを使って以下の各関数を定義せよ.

(1) f1(n) = 1 + 2 + · · · + n

(2) f2(n) = 1 × 2 × · · · × n

(3) f3(n, x) = 1 × x1 + 2 × x2 + · · · + n × xn

12.int -> boolなる型の関数fは,fがtrueを返す要素の集合と見なせる.例えば,

fn x => x = 1 orelse x = 2 orelse x = 3

は{1, 2, 3}の表現である.この表現に対する以下の集合操作関数を定義せよ.ただし,SMLではexp1とexp2の論理和はexp1orelse exp2と書木,論理積はexp1 andalso exp2と書く.

(1) 空集合emptyset.

75& %

Page 77: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

(2) 与えられた要素nのみからなる集合{n}を返す関数singleton.

(3) 要素を集合に加える関数insert.(4) 要素が集合に含まれているか否かをテストする関数member.(5) 以下の集合論演算.union,intersection,difference.

76& %

Page 78: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

4. MLの型システム

77& %

Page 79: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

型推論と型チェック

MLは

1. 任意の式の型を自動推論する.

2. さらに,推論される型は最も一般的な多相型.

78& %

Page 80: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

自動型推論MLプログラムは型宣言を必要としない.

fun products f n = if n = 0 then 1

else f n * products f (n - 1)

これは,例えば,Lispなどの型なし言語と同等:

(defun products (f n)

(if (<= n 0) 1

(* (funcall f n) (products f (- n 1)))))

しかし,MLはその型を自動推論する.

val products = fn : (int -> int) -> int -> int

79& %

Page 81: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

これにより,完全な静的型チェックが可能.

fun factorial n = products n (fn x => x);

stdIn:1.19-1.40 Error: operator and operand don’t agreeoperator domain: intoperand: ’Z -> ’Zin expression: products n ((fn x => x))

LISPなどと比べると,その利点は明らか.

# (defun factorial (n)

(products n #’(lambda (x) x)))

factorial...

(· · · (factorial 4) · · ·)Worng type argument: integer-or-marker-p (lambda (x) x)

80& %

Page 82: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

多相性一般にプログラムは多くの型を持つ.

fun id x = x

idは,

int -> int

string -> string.

その他τ-> τの形の無限に多くの型をもつ.

MLは,これらすべてを正確に表現する型を推論する.

val id = fn : ’a -> ’a

ここで,’aは任意の型を代表する型変数.

81& %

Page 83: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

型変数は自動的に具体化(instantiate)される.

# id 21;

val it = 21 : int# id "Standard ML";

val it = ”Standard ML” : string# id products;

val it = fn : (int -> int) -> int -> int# fn x => id id x

val it = fn : ’a -> ’a

以下のようなものも可能

# fn x => id id x;

val it = fn : ’a -> ’a# fun twice f x = f (f x);

val twice = fn : (’a -> ’a) -> ’a -> ’a

82& %

Page 84: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

# twice cube 2;

val it = 512 : int# twice (fn x => x ^ x) "ML";

val it = ”MLMLMLML” : string# fn x => twice twice x;

val it = fn : (’a -> ’a) -> ’a -> ’a# it (fn x => x + 1) 1;

val it = 5 : int

83& %

Page 85: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

レコード

84& %

Page 86: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

レコード型とレコード式

レコード型の構文

{l1 : τ1,· · ·,ln : τn}

• l1, · · ·, lnはレコードラベル• liは名前か数字のどちらか.

• τ1, · · ·, τnはどのような型でもよい.

type malt = {Brand:string, Distiller:string,

Region:string, Age:int}

85& %

Page 87: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

レコード式の構文

{l1 = exp1,· · ·,ln = expn}expiはどのような式でもよい.

型の規則exp1 : τ1 · · · expn : τn

{l1 = exp1, · · ·, ln = expn} : {l1 : τ1, · · ·, ln : τn}

# val myMalt= {Brand = "Glen Moray",

Distiller = "Glenlivet",

Region = "the Highlands", Age = 28};val myMalt = {Age = 28, Brand = ”Glen Moray”,

Distiller = ”Glenlivet”,Region = ”the Highlands” }

: {Age : int, Brand : string, Distiller : string, Region : string}

86& %

Page 88: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

型付き言語の基本原理:

expressions can be freely combined as far as they are type correct.

により他の構文と自由に組み合わせることが可能.

# fun createGlen’sMalt (name,age) =

{Brand = name, Distiller = "Glenlivet",

Region = "the Highlands", Age = age};val createGlen’sMalt =

fn : ’a * ’b -> {Age:’b, Brand:’a, Distiller:string, Region:string}

87& %

Page 89: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

レコードの操作

#l eにより,レコード式eのラベル lの値を取り出す.

# #Distiller myMalt;

val it = ”Glenlivet” : string# fun oldMalt (x:{Brand:’a, Distiller:’b,

Region:’c, Age:int}) =

#Age x > 18;

val oldMalt = fn : {Age:int, Brand:’a, Distiller:’b, Region:’c} -> bool# oldMalt myMalt;

val it = true : bool

88& %

Page 90: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

レコードパターン

{l1 = pat1,· · ·,ln = patn}{l1 = pat1,· · ·,ln = patn,...}を関数とともに使用すれば,フィールドを取り出せる.

# fun oldMalt {Brand, Distiller, Region, Age} = Age > 18

val oldMalt = fn : {Age:int, Brand:’a, Distiller:’b, Region:’c} -> bool

89& %

Page 91: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $# val {Brand = brand, Distiller = distiller,

Age = age, Region = region} = myMalt;

val age = 28 : intval brand = ”Glen Moray” : stringval distiller = ”Glenlivet” : stringval region = ”the Highlands” : string# val {Region = r, ...} = myMalt;

val r = ”the Highlands” : string# val {Region, ...} = myMalt;

val Region = ”the Highlands” : string# val distiller = (fn {Distiller,...} => Distiller) myMalt;

val distiller = ”Glen Moray” : string# fun getRegion ({Region, ...}:malt) = Region;

val getRegion = fn : {Age:’a, Brand:’b, Distiller:’c, Region:’d } -> ’d# getRegion myMalt;

val it = ”the Highlands” : string

90& %

Page 92: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

Standard MLにおける型に関する制限

レコードを多相関数と一緒に使おうとすると旨くいなかい.

fun name {Name = x, Age =a} = x

は許されるが,fun name x = #Name x

stdIn:17.1-17.21 Error: unresolved flex record(can’t tell what fields there are besides #name)

となる.

これは現在の理論と実装技術の欠陥.(すべての言語に共通)

SML]では,解決済:# fun name x = #Name x;

val name : [’a,’b.’a#Name:’b ->’b]

91& %

Page 93: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

リストを使ったプログラミング

92& %

Page 94: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

リストの構造

リストはポインターで実現された以下のような構造.

v1 v2 v3 . . . vn nilL :

この構造から,リストの以下の性質が理解できる.

1. リストは,その大きさによらず,一つのポインタで表現.

2. 空のリストはnilと呼ばれる特殊なポインターで表現.

3. リストの要素は先頭からしかアクセスできない.

4. 先頭要素を取り除いたものもやはりリスト.先頭に要素を付け加えたものもやはりリスト.

93& %

Page 95: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

リストの数学的理解

リストは組みが入れ子になった,以下のような構造と理解することができる.

(v1, (v2, · · · (vn, nil) · · ·))Aを要素の集合とし,Aの要素をv1, v2, . . . , vnの様に書く.Nilを集合{nil}とする.2つの集合A,Bのデカルト積A × Bを以下の様に定義する.

A × B = {(a, b)|a ∈ A, b ∈ B}するとn個の要素のリストの集合は以下のように与えられる.

A × (A × (· · · (A︸ ︷︷ ︸n個のA

×Nil) · · ·))

従って,リスト全体の集合は以下の等式で表される.

L = Nil ∪ (A × L)

94& %

Page 96: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

この等式の解を以下の手順で求めることができる.

1. 集合列Xiを以下の様に定義する

X0 = Nil

Xi+1 = Xi ∪ (A × Xi)

もす上記の等式がLに関して解を持てば, 各iについて

Xi ⊆ L

が成り立つことを示せる.

2. この集合属を用いて,X =

⋃i≥0

Xi

と定義すると,Xはリストに関する等式を満たすこと,従って求める解であることが分かる.

95& %

Page 97: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

リスト型 : τ list

τ listは,要素の型をτとするリスト型.例:

• int list : integer lists.

• int list list : lists of integer lists.

• (int -> int) list : lists of integer functions.

96& %

Page 98: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

リスト生成関数

リストを生成生成のための定数と関数

val nil : ’a list

infixr 5 ::

val op :: : ’a * ’a list -> ’a list

これらを用いて,v1, · · ·, vnを要素とするリストは

v1 :: v2 :: · · · :: vn :: nil

と書ける.

以下の略記法も用意されている.

[] =⇒ nil

[exp1,exp2,· · ·,expn] =⇒ exp1 :: exp2 :: · · · :: expn :: nil

97& %

Page 99: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

リストの例

# nil;

val it = [ ] : ’a list# 1 :: 2 :: 3 :: nil;

val it = [1,2,3 ] : int list# [[1],[1,2],[1,2,3]];

val it = [[1 ],[1,2 ],[1,2,3 ]] : int list list# [fn x => x];

val it = [fn] : (’a -> ’a) list

98& %

Page 100: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

リスト生成の例

[1,2,3,4,...,n]を生成する関数.

最初のトライ:

# fun mkList n = if n = 0 then nil

else n :: f (n - 1);

val mkList = fn : int -> int list# mkList 3;

val it = [3,2,1] : int list

再挑戦# fun mkList n m = if n = 0 then nil

else (m - n) :: f (n - 1) m

val mkList = fn : int -> int-> int liist# mkList 3 4;

val it = [1,2,3] : int list

99& %

Page 101: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

よりまともなコード

# fun mkList n =

let

fun f n L = if n = 0 then L

else f (n - 1) (n::L)

in

f n nil

end;

val mkList = fn : int -> intlist# mkList 3;

val it = [1,2,3] : int list

これのほうが簡潔でかつ効率的.末尾再帰で考えよ.

100& %

Page 102: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

パターンを用いたリストの分解

リスト処理のための基本演算はパターンマッチング:

case E0 of nil => E1| (h::t) => E2(h,t)

これは以下の処理を行う.

1. E0を評価しリストの値Lを得る.

2. もしLがnilならE1を評価.

3. もしLがh::tの形なら, hをLの先頭要素に,tをLの残りの要素に束縛し,この下でE2(h, t)を評価する.

101& %

Page 103: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

v2 v3 . . . vn nil

E2(h, t)

v1

v2 v3 . . . vn nilv1

| (h::t) => E2(h,t)case E0 of nil => E1

evaluation of case

102& %

Page 104: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

# case nil of nil => 0 | (h::t) => h;

val it = 0 : int# case [1,2] of nil => 0 | (h::t) => h;

val it = 1 : int

パターンマッチングを用いた簡単な例

fun length L = case L of nil => 0

| (h::t) => 1 + length t;

103& %

Page 105: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

パターンマッチングの一般形

case exp of pat1 => exp1 | pat2 => exp2 | · · · | patn => expn

ここでpatiは以下の要素から構成されるパターン

•定数,

•変数,

•データ構成子.リストの場合以下の構成子パターンがある– nil,

– pat1::pat2,

– [pat1,· · ·,patn]

104& %

Page 106: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

fun zip x = case x of (h1::t1,h2::t2) =>

(h1,h2) :: zip (t1,t2)

| => nil

fun unzip x = case x of (h1,h2)::t =>

let val (L1,L2) = unzip t

in (h1::L1,h2::L2)

end

| => (nil,nil)

“ ”は何にでもマッチするワイルドカードパターン.

パターンは共通部分があってもよく網羅的で無くてもよい.

fun last L = case L of [x] => x

| (h::t) => last t

105& %

Page 107: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

有用な糖衣構文

fun f pat1 = exp1| f pat2 = exp2...

| f patn = expn

=⇒

fun f x = case x of

pat1 => exp1| pat2 => exp2...

| patn => expn

fn pat1 => exp1| pat2 => exp2...

| patn => expn

=⇒

fn x => case x of

pat1 => exp1| pat2 => exp2...

| patn => expn

106& %

Page 108: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

パターンを用いた関数定義の例

fun length nil = 0

| length (h::t) = 1 + length t

fun fib 0 = 1

| fib 1 = 1

| fib n = fib (n - 1) + fib (n - 1)

107& %

Page 109: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

汎用のリスト処理関数

リスト処理関数の再考:

fun sumList nil = 0

| sumList (h::t) = h + sumList t

これは,以下の処理パターンの特殊な場合と見なせる.

1. もしリストがnilならある決められた値Zを返す.

2. もしリストがh::tの形なら,自分自身を用いいてtに対する値を再帰的に計算し結果Rを求め,

3. hとRから,ある関数fを用いて最終結果を計算する.

sumListのばあい,Z = 0およびf (h,R) = h + Rと取ればよい.

108& %

Page 110: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

以下の高階関数は,上記のパターンを実際に実現する関数.

fun foldr f Z nil = Z

| foldr f Z (h::t) = f(h,foldr f Z t)

これを用いれば,個々のリスト処理関数を,以下のような適用によって簡単に実現できる.

foldr (fn (h,R) => exp) Z

ここで,

• Zはnilに対する値.

• fn (h,R) => expは,2番目以降のリストを処理した結果Rtoリストの先頭要素hから最終結果を計算する関数.

109& %

Page 111: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

# val sumList = foldr (fn (h,R) => h + R) 0 ;

val sum : int list -> int

���������� � ��

�������

(fn (h,R) => expr) �����

foldr

��� ������������

Z L

���� �!���������������"�#�$ ��� ����

110& %

Page 112: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

プログラミング例

関係Rの推移的閉包R+は以下のように定義される関係である.

R+ = {(x, y) | ∃n∃z1· · ·∃zn x = z1, y = zn,(zi, zi+i) ∈ R(1 ≤ i ≤ n − 1)}

与えられたRからR+を計算するプログラムを定義してみよう.

1. アルゴリズムを設計ために,まず,R+の定義を実行可能な(構成的な)なもに書き換える.R+の中に含まれるべき要素の性質を考えると,十分に大きなNを取ると,R+は以下のように書き直せる.

R+ = R1 ∪ R2 ∪ · · · ∪ RN

111& %

Page 113: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

2. 次に,Rkを以下のように再帰的に定義する.

R1 = R

Rk = R × Rk−1 (k ≥ 2)

ここで,×は以下のような演算である.R × S = {(x, y)|∃a (x, a) ∈ R, (a, y) ∈ S}

112& %

Page 114: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

3. R+を定義する.まず,RN = R1 ∪ · · · ∪ RNをNに関して関数として定義する.以前でてきたaccumulate関数の考え方を使えば,hを和集合演算,f (k) = Rk,z = ∅として,

RN = h(f (N), · · · , h(f (1), z) · · ·) = ΛNk=1(h, f, z)

と書ける.Nは,Rに含まれる最大のチェーンの長さ以上であればよい.その一つの見積もりとしてRの要素の数ととることができる.以上から,以下のような定義が得られる.

R+ = Λ|R|k=1(h, f, z)

113& %

Page 115: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

4. R × S,Rn,R+をそれぞれ計算する関数timesRel,powerRel,tcのコードを上に与えた定義に従って書き下す.

fun timesRel (R,S) =

foldr (fn ((x,a),r) =>

foldr (fn ((b,y),rs) =>

if a=b then (x,y)::rs

else rs)

r S)

nil R;

fun powerRel r 1 = r

| powerRel r n = timesRel (r,powerRel r (n - 1));

fun tc R =

accumulate (op @) nil (powerRel R) (length R)

114& %

Page 116: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

すると,以下のような動作をする関数が得られる.

# tc [(1,2),(2,3),(3,4)];

val it = [(1,4),(1,3),(2,4),(1,2),(2,3),(3,4)]: (int * int) list

115& %

Page 117: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

練習問題 (4)

1. 以下の書く関数を再帰的関数として直接定義せよ.

(1) 与えられた整数リストの和を求める関数sumList.(2) 与えられた値が与えられたリストに入っているか否かをテストする関数member

(3) 与えられたリストから重複する要素を取り除いて得られるリストを返す関数unique

(4) filter 型’a -> boolを持つ関数Pと型’a listのリストを受け取り,Pがtrueを返す値のみからなるリストを返す関数filter

(5) 以下のようにリストのリストを一つのリストにする関数flatten:

# flatten [[1],[1,2],[1,2,3]];

val it = [1,1,2,1,2,3 ] : int list

116& %

Page 118: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

(6) 文字列のリストLと文字列dを受け取り,Lの中の文字列をすべてdを区切り記号として繋げて得られる一つの文字列を返す関数splice.たとえば以下のような動作をする.

# splice (["","home","ohori","papers"],"/");

val it = ”/home/ohori/papers” : string

2. 以下の関数をfoldrを使って定義せよ.

(1) 以下の各関数.map,flatten,member,unique,prefixList,permutations

(2) リストと述語P(すなわちboolの型の値を返す関数)を受け取り,リストの総ての要素が述語Pを満たすか否かをテストする関数forall.同様に,リストの中に述語Pを満たす要素が存在するか否かをテストする関数exists.上記の定義から,任意のPに対してexists P nilはfalse

であり,forall P nilはtrueであることに注意.

117& %

Page 119: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

2.1.整数のリストの先頭からのそれぞれの要素までの和のリストを返す関数prefixSum.例えば,与えられたリストが[a1, a2, · · ·, an]であれば,[a1, a1 + a2, · · · , a1 + · · · an−1, a1 + · · · + an]を返す.

3. foldr は,nil と :: で構成されているリストの構造に従って再帰的に処理する上で威力を発揮するが,再帰的な処理がうまく記述できない問題に対しては,うまく利用できない.たとえば,リストの最後の要素を求める関数や,リストを反転させる関数などはうまく記述できない.これらの処理は,リストの要素を逆順に処理する関数があれば,簡単に定義できる.SMLでは,以下のような動作をするfoldlも定義されている.

foldr f Z [a1,· · ·,an−1,an] = f (an, f (an−1, f (· · · , f (a1, Z) · · ·)))(1) foldlを実現する関数定義を与えよ.(2) foldlを用いてrevを定義せよ.

118& %

Page 120: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

4. 関数Rの表現が重複する要素を含まない時,その豹変は正規形であるということにする.

(1) Rが正規形であってもtc Rが正規形でないような例をあげよ.

(2) 正規形のRに対しては,常に正規形の表現を返すようにtc

の定義を改良せよ.

関係に関する以下の関数を定義せよ.

(1) 関係Rが与えられた時,(a, b)は関係しているかをテストする関数isRelated.

(2) 与えられた関係Rと与えられた要素aに対して,集合を{x | (a, x) ∈ R}を計算する関数targetOf.

(3) 関係Rと要素aに対して集合{x | (x, a) ∈ R}を計算する関数sourceOf.

(4) 関係Rの逆関係R−1を求める関数inverseRel

119& %

Page 121: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

データ型の定義

120& %

Page 122: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

datatype文は新しい型を定義する

例: 二分木

型τの値をノードに持つ二分木を型τの二分木と言うということにする.型τの二分木は,再帰的に以下のように定義される.

1. 空の木は型τの二分木である.

2. もしvがτの値,T1とT2が型τの二分木なら(v, T1, T2)も型τの二分木である.

このような再帰的な定義によって定まる型は,直接以下の構文で導入できる.

# datatype ’a tree =

Empty

| Node of ’a * ’a tree * ’a tree;

datatype ’a tree = Empty | Node of ’a * ’a tree * ’a tree

121& %

Page 123: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

この定義の後EmptyとNodeは’a tree型データの値を構成する構成子(関数)として使用できる.

# Empty;

val it = Empty : ’a tree# Node;

val it = fn : ’a * ’a tree * ’a tree -> ’a tree# Node (1,Empty,Empty);

val it = Node (1,Empty,Empty) : int tree# Node ((fn x => x),Empty,Empty);

val it = Node (fn,Empty,Empty) : (’a -> ’a) tree

122& %

Page 124: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

Node("a",Node("b",Empty,Empty),

Node("c",Node("d",Empty,Empty),Empty))

� �

� �

"a"

"c""b"

"d" � ��������� �����

木のpre-order表現a(b()())(c(d()())()).

123& %

Page 125: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

二分木は文字列で系統的に表現できる.その一つは,以下のように定義されるpre-order表現である.

• Emptyは空文字列で表現する.• Node(a,L,R)は,a(SL)(SR)と表現する.ここで,SLおよびSRはRとLのpre-order表現である.

この表現は,二分木を

1. 木のルール,

2. 左部分木,

3. 右部分木

とたどって得られる文字列である.

124& %

Page 126: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

pre-ordre表現から木再構成関数は,以下のように定義できる.

fun fromPreOrder s =

let fun decompose s = ...

(* 文字列を‘(’と‘)’を区切りとして分解する.*)

in if s = "" then Empty

else let val (root,left,right) = decompose s

in Node(root,

fromPreOrder left,

fromPreOrder right)

end

decomposeは以下のような分割を行う.

# decompose "a(b()())(c(d()())())";

val it = (”a”,”b()()”,”c(d()())()”) : string * string * sting

125& %

Page 127: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

fun decompose s =

let fun searchLP s p = ...

(* 位置pからsを走査し最初の左括弧の位置を返す.*)

fun searchRP s p n = ...

(* 位置pからsを走査しn個外側の右括弧の位置を返す.*)

val lp1 = searchLP s 0

val rp1 = searchRP s (lp1+1) 0

val lp2 = searchLP s (rp1+1)

val rp2 = searchRP s (lp2+1) 0

in (substring (s,0,lp1),

substring (s,lp1+1,rp1-lp1-1),

substring (s,lp2+1,rp2-lp2-1))

end

126& %

Page 128: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

datatype構文の一般形

datatype typeSpec =

Con1 〈of type1〉| Con2 〈of type2〉

...

| Conn 〈of typen〉

• typeSpecは定義する型の名前

• =の右側が新しい型の構造の定義

127& %

Page 129: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

パターンマッチングを用いたdatatypeの利用

以下のcase構文において

case exp of pat1 => exp1 | pat2 => exp2 | · · · | patn => expn

patiは以下の要素を含むパターン:

1. 変数,

2. 定数,

3. datatype文で定義済のデータ構成子,

4. ワイルドカードパターン:

128& %

Page 130: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

# case Node ("Joe",Empty,Empty) of Empty => "empty"

| Node (x, , ) => x;

val it = ”Joe” : string

木の高さの計算の例

1. 空の木の高さは0

2. Node(a,L,R)の形の木の高さは1 + max(Rの高さ, Lの高さ)

従って,以下の様にコードできる

# fun height t =

case t of Empty => 0

| Node ( ,t1,t2) => 1 + max(height t1, height t2);

val height = fn : ’a tree -> int

129& %

Page 131: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

パターンマッチングの例

fun height Empty = 0

| height (Node( ,t1,t2)) = 1 + max(height t1, height t2)

fun toPreOrder Empty = ""

| toPreOrder (Node(s,lt,rt)) =

s ^ "(" ^ toPreOrder lt ^ ")"

^ "(" ^ toPreOrder rt ^ ")"

130& %

Page 132: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

システム定義のデータ型

Lists

infix 5 ::

datatype ’a list = nil | :: of ’a * ’a list

真理値datatype bool = true | false

bool型を操作する特殊構文:

exp1 andalso exp2 =⇒ case exp1 of true => exp2| false => false

exp1 orelse exp2 =⇒ case exp1 of false => exp2| true => true

if exp then exp1 else exp2 =⇒ case exp of true => exp1| false => exp2

131& %

Page 133: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

そのほかのシステム定義データ型:

datatype order = EQUAL | GREATER | LESS

datatype ’a option = NONE | SOME of ’a

exception Option

val valOf : ’a option -> ’a

val getOpt : ’a option * ’a -> ’a

val isSome : ’a option -> bool

132& %

Page 134: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

プログラミング例 : 辞書

type ’a dict = (string * ’a) tree

val enter : string * ’a * ’a dict -> ’a dict

val lookUp : string * ’a dict -> ’a option

• enterは与えられた辞書に項目を追加して得られる新しい辞書を返す.

• lookUpは与えられたキーの値を辞書から探す.

効率よい辞書を実現するために,二分木を,以下の性質を満たす二分探索木として用いる.任意のNode(key,L,R)の形のノードに対して,

1. Lの中のキーはkeyよりも小さい,

2. Rの中のキーはkeyよりも大きい

133& %

Page 135: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

fun enter (key,v,dict) =

case dict of

Empty => Node((key,v),Empty,Empty)

| Node((key’,v’),L,R) =>

if key = key’ then dict

else if key > key’ then

Node((key’,v’),L, enter (key,v,R))

else Node((key’,v’),enter (key,v,L),R)

fun lookUp (key,Empty) = NONE

| lookUp (key,Node((key’,v),L,R)) =

if key = key’ then SOME v

else if key > key’ then lookUp (key,R)

else lookUp (key,L)

134& %

Page 136: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

無限のデータ構造

もちろん,我々は有限のデータしか扱えない.したがって,

fun fromN n = n :: (fromN (n+1));

などは役に立たない.

無限のデータ表現の鍵: 必用になるまで計算を遅延する.

計算遅延機構: fn () => exp

遅延評価の幾つかの例

fun cond c a b = if c then a () else b();

val cond = fn : bool -> (unit -> unit)-> (unit -> unit)-> unitcond true (fn () => print "true") (fn () => print "false");

135& %

Page 137: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

無限リストを表すデータ型定義

datatype ’a inflist =

NIL | CONS of ’a * (unit -> ’a inflist)

例:

fun FROMN n = CONS(n,fn () => FROMN (n+1));

# FROMN 1;

val it = CONS (1,fn) : int inflist# val CONS(x,y) = it;

val x = 1 : intval y = fn : unit -> int inflist# y ();

val it = CONS (2,fn) : int inflist

136& %

Page 138: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

inflist操作関数.

fun HD (CONS(a,b)) = a

fun TL (CONS(a,b)) = b()

fun NULL NIL = true | NULL = false

例:

# val naturalNumbers = FROMN 0;

val naturalNumbers = CONS (0,fn) : int inflist# HD naturalNumbers;

val it = 0 : int# TL naturalNumbers;

val it = (1,fn) : int inflist# HD (TL(TL(TL it)));

val it = 4 : int

137& %

Page 139: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

inflistを操作するための戦略:

1. hd,tl,nullを使ってリスト処理を設計する.

2. 以下の置き換えを行う.

hd =⇒ HD

tl =⇒ TL

null =⇒ NULL

h::t =⇒ CONS(h,fn () => t)

例:

fun NTH 0 L = HD L

| NTH n L = NTH (n - 1) (TL L)

int -> ’a inflist -> -> ’a# NTH 100000000 naturalNumbers;

val it = 100000000 : int

138& %

Page 140: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

少々複雑な例:通常のリストの場合:

fun filter f l = if null l then nil

else if f (hd l) then

hd l :: (filter f (tl l))

else filter f (tl l);

無限リストの場合:

fun FILTER f l = if NULL l then NIL

else if f (HD l) then

CONS(HD l,fn () => (FILTER f (TL l)))

else FILTER f (TL l);

139& %

Page 141: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

エラトステネスの篩:2から始まる整数の無限列に対して以下の処理を繰り返す.

1. 先頭要素を取りだして出力する.

2. 残りのリストから,先頭要素で割りきれるすべての要素を取り除く

コードの例

fun SIFT NIL = NIL

| SIFT L =

let val a = HD L

in CONS(a, fn () =>

SIFT (FILTER (fn x => x mod a <> 0)

(TL L)))

end

140& %

Page 142: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

# val PRIMES = SIFT (FROMN 2);

val PRIMES = CONS(2,fn) : int inflist# TAKE 20 PRIMES;

val it = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71 ]: int list;

# VIEW (10000,10) PRIMES;

val it = [104743,104759,104761,104773,104779,104789,104801,104803,104827,104831 ] : int list

141& %

Page 143: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

MLの手続き的機能

142& %

Page 144: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

参照型

’a ref型とrefデータ構成子

infix 3 :=

val ref : ’a -> ’a ref

val ! : ’a ref -> ’a

val := : ’a ref * ’a -> unit

簡単な例:

- val x = ref 1;

val x = ref 1 : int ref- !x;

val it = 1 : int- x:=2;

val it = () : unit- !x;

143& %

Page 145: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

val it = 2 : int

144& %

Page 146: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

参照型を操作するプログラムの結果は,式の評価順序に依存する.

MLに置ける評価順序:

• let val x1 = exp1 · · · val xn = expn in exp end構文では,exp1, . . . , expnをこの順に評価した後,expを評価する.

•組(exp1,· · ·,expn)やレコード{l1 = exp1,· · ·, ln = expn}は左から右に評価する.

•関数適用式epx1 exp2では,まずexp1を評価し,関数fn x =>

exp0を取りだし,次にexp2を評価し結果vを得,xをvに束縛し,exp0を評価する.

145& %

Page 147: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

評価順序を制御する構文

• (exp1; · · ·; expn)

• exp1 before exp2

• while exp1 do exp2

146& %

Page 148: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

プログラミング例

新しい名前を生成する関数:gensym

• gensym : unit -> string.

•呼ばれる毎に,"a","b",· · ·,"z","aa","ab",· · ·,"az","ba",· · · の順で英文字からなる新しい名前を返す.

以下のデータ構造を使用:

•最後に生成した名前の内部表現を記憶する参照型データstate.

• stateから次の名前を生成する関数next

•内部表現stateを文字列に変換する関数toString.

147& %

Page 149: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

これらを使えば,gensymは以下のようにコードで実現できる.

local

val state = · · ·fun toString = · · ·fun next s = · · ·

in

fun gensym() = (state:=next (!state);

toString (!state))

end

148& %

Page 150: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

文字列の内部表現

長さkの文字列snsn−1 · · · s1を [ord(s1), ord(s2), · · ·, ord(sn)]と表現.

nextは,以下のようにこのリストに1を足す.

val state = ref nil : int list ref

fun next nil = [ord #"a"]

| next (h::t) = if h = ord #"z" then

ord #"a" :: (next t)

else (h+1::t)

149& %

Page 151: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

参照型と参照透明性

プログラムに関する数学的分析の基本:

プログラムの意味はその構成要素の意味によって決定される.

言い換えれば,

プログラムの意味は,そのプログラムの一部を等価なもので置き換えても変化しない.

これは,参照透明性と呼ばれる,数学的推論の基本原則の例:

2つの等価な式は,文の意味を変えること無く互いに置き換えることができる.

150& %

Page 152: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

例:

(fn x => x = x) exp

exp = exp

は同一の意味をもつ.

しかし, 参照型があるMLではこの性質は成り立たない,

# (fn x => x = x) (ref 1);

val it = true : bool# ref 1 = ref 1;

val it = false : bool

151& %

Page 153: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

参照型と値多相性

値多相性:多相型を持ちうる式は値式に限る.

# ref (fn x => x);

stdIn:19.1-19.16 Warning: type vars not generalized because ofvalue restriction are instantiated to dummy types (X1,X2,...)

val it = ref fn : (?.X1 -> ?.X1 ) ref

もし以下のような式に多相型を許せば

ref (fn x => x) : (’a -> ’a) ref

以下のような問題が起る.

val polyIdRef = ref (fn x => x);

polyIdRef := (fn x => x + 1);

(!polyIdRef) "You can’t add one to me!";

値多相性は,この問題を回避するために導入された制限.152& %

Page 154: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

例外処理

例外 : 制御された “goto”.exception文は新しい例外を定義する.

exception exnIdexception exnId of τ

raiseは例外を生成する.

raise exnIdraise exnId exp

153& %

Page 155: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

例:

# exception A;

exception A# fun f x = raise A;

val f = fn : ’a -> ’b# fn x => (f 1 + 1, f "a" andalso true);

val it = fn : ’a -> int * bool

154& %

Page 156: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

システム定義の例外

exception name meaningBind bind failureChr illegal character codeDiv divide by 0Empty illegal usage of hd and th

Match pattern matching failureOption empty option dataOverflow

Size array etc too bigSubscript index out of range

155& %

Page 157: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

exp handle exnPat1 => handler1| exnPat2 => handler2

...

| exnPatn => handlern

例外処理:

1. 例外状態検出

2. システムは呼び出し系列を逆にたどり例外ハンドラを探す

3. もしハンドラ─が見つかったら,例外とハンドラ─のパターンマッチングを試みる.

4. もしマッチするパターンを持つハンドラ─が見つかれば,そのパターンを例外に束縛し対応するハンドラ─を評価する.

5. もしマッチするハンドラ─が見つからなければ式の評価を中断しトップレベルに戻る.

156& %

Page 158: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

# exception Undefined;

exception Undefined# fun strictPower n m = if n = 0 andalso m = 0 then

raise Undefined

else power n m;

val strictPower = fn : int -> int -> int# 3 + strict power 0 0;

uncaught exception Undefined# 3 + (strictPower 0 0 handle Undefined => 1);

val it = 4 : int

157& %

Page 159: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

プログラミング例 (1)

type ’a dict = (string * ’a ) tree

val enter : (string * ’a) * ’a dict -> ’a dict

val lookUp : string * ’a dict -> ’a option

exception NotFound

fun lookUp (key,Empty) = raise NotFound

| lookUp (key,Node((key’,v),L,R)) =

if key = key’ then v

else if key > key’ then lookUp (key,R)

else lookUp (key,L)

val lookUp : string * ’a dict -> ’a

fun assoc (nil,dict) = nil

| assoc ((h::t),dict) =

(h, lookUp (h,dict)):: assoc (t,ditc)

handle NotFound => (print "Undefined key."; nil)

158& %

Page 160: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

プログラミング例 (2)

fun lookAll key dictList =

let exception Found of ’a

fun lookUp key Empty = ()

| lookUp key (Node((key’,v),L,R)) =

if key = key’ then raise Found v

else if key > key’ then lookUp key R

else lookUp key L

in (map (lookUp key) dictList; raise NotFound)

handle Found v => v

end

159& %

Page 161: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

練習問題 (5)

1. decompose関数を完成せよ.

# decompose "a(b()())(c(d()())())";

val it = (”a”,”b()()”,”c(d()())()”) : string * string * sting

2. pre-order表現に加え,以下の表現がある.

• post-order表現木を以下の順でたどって得られる表現(1) 左部分木(2) 右部分木(3) ルートノード.

• in-order表現木を以下の順でたどって得られる表現(1) 左部分木

160& %

Page 162: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

(2) ルートノード,

(3) 右部分木.

以下の関数を定義せよ.

• post-order表現から木を再構築する関数fromPostOrder.• in-order表現から木を再構築する関数fromInOrder.•木のpost-order表現を返す関数toPostOrder.•木の in-order表現を返す関数toInOrder.

161& %

Page 163: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

3. 二分木上の以下の各関数を定義せよ,

•木の中のノードの総数を求める関数nodes.•木の中の総ての値の和を求める関数sumTree.•木の中のdデータに与えられた関数を適用して得られる値で置き換えて得られる木を返す関数mapTree : (’a -> ’b) -> ’a tree -> ’b tree

4. 木に対して,リストのfoldrと類似の動作する関数treeFold.この関数は以下の引数を取る.

(1) 処理対象の木t.(2) 木が空の時返す値z

(3) 部分木の処理結果とノードの値から最終的な値を計算する関数f.

この関数は以下のような動作をする.

162& %

Page 164: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

# fun treeFold f z Empty = z

| treeFold f z (Node (x,L,R)) = · · ·· · ·

val treeFold = fn : (’a * ’b * ’b -> ’b) -> ’b -> ’a tree -> ’b

(1) treeFoldの定義を完成させよ.(2) 以下をtreeFoldを使って定義し直せ.nodes, sumTree, and

mapTree using treeFold.

5. 型’a list -> ’a option を持つ以下の関数を定義せよ.

(1) リストの先頭要素を取り出す関数:car.(2) 先頭要素を取り除いたリストを返す関数:cdr.(3) リストの先頭要素を取り出す関数:last.

6. 与えられたリストのデータからなる辞書を生成する関数makeDict : (string * ’a) list -> ’a dict.makeDictを

163& %

Page 165: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

用いてlookUpのテストを行え.

7. 以下の関数を定義せよ.

type (’a,’b) dict = (’a * ’b) tree

val makeEnter : (’a * ’a -> order)

-> ’a * ’b * (’a,’b) dict

-> (’a,’b) dict

val makeLookUp : (’a * ’a -> order)

-> ’a * (’a,’b) dict -> ’b

ただしmakeEnterは比較関数を受け取り辞書への登録関数を返す関数.makeLookupは比較関数を受け取り辞書の探索関数を返す関数.

8. enter とlookUp 関数を(int,string) dictの型の辞書に対して定義せよ.

164& %

Page 166: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

9. 偶数の無限リストevenNumbersをnaturalNumbersからFILTER

を使って定義せよ.例えば,以下のような動作をする.

# NTH 10000000 evenNumbers;

val it = 20000000 : int

10.無限リスト上の以下の関数を定義せよ.

•最初のn個の要素を取り除いて得られるリストを返す関数:DROP : int -> ’a inflist -> ’a inflist.

•最初のn個の要素からなるリストを返す関数:TAKE : int

-> ’a inflist -> ’a list that returns the list of the first nelements in a given infinite list.

• n番目からm個の要素をリストとして返す関数:VIEW : int

* int -> ’a inflist -> ’a list.

11.genSymの定義を完成せよ.

165& %

Page 167: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

12.文字のリストを受け取り,その文字を使って以前のgensym同様に文字列を作り出す関数

makeGensym : char list -> unit -> string

を定義せよ.例えば,makeGensym [#"S",#"M",#"L"]は"S","M", "L",

"SS","SM","SL","MS","MM","ML","LS",· · ·の順で文字列を作り出す関数を返す.

13.enterの定義を変更し,同一のキーに追加しようとするとDuplicateEntry例外を発生させるようにせよ.

14.整数のリストの積を計算する関数を定義せよ.ただし,途中で0を検出した場合,以降の処理を中断し直ちに0を返すような動作をするものとする.

166& %

Page 168: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

SYNTAX OF THE STANDARD ML CORE LANGUAGE

167& %

Page 169: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

表記の約束

定義は,definition := structure1 explanation1

| structure2 explanation2...

| stricture explanation

のように書く.省略可能な文法要素は〈optional〉と書く.

[E1,· · ·,En] はE1からEnまでのどれかを表す.E* Eの0回以上の繰り返しE+ Eの1回以上の繰り返し

168& %

Page 170: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

定数と識別子

scon := int | word | real | string | char (constant)int := 〈~〉[0-9]+ (decimals)

| 〈~〉0x[0-9,a-f,A-F]+ hexa decimal notation

word := 0w[0-9]+ (unsigned decimal)| 0wx[0-9,a-f,A-F]+ (unsigned hexadecimal)

real := integers .[0-9]+ [E,e]〈~〉[0-9]+ (reals)| integers .[0-9]+| integers [E,e]〈~〉[0-9]+

char := #"[printable,escape]" (characters)string := " [printable,escape]∗ " (strings)

printable \と"を除く印字可能な文字

169& %

Page 171: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

escape := \ 警告文字 (ASCII 7)| \b バックスペース(ASCII 8)| \t タブ(ASCII 9)| \n 改行文字(ASCII 10)| \v 垂直タブ(ASCII 11)| \f フォームフィード(ASCII 12)| \r リターン (ASCII 13)| \^C 制御文字C| \\ \自身| \" "自身| \ddd dddをコードとする文字| \f · · · f\ fがフォーマット文字の時 f· · ·fを無視| \uxxx UNICODE(?)

170& %

Page 172: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

識別子のクラス

class contents notevid variables longtyvar type variables startintg with ’

tycon type constructors longlab record labelsstrid structure names longsigid signature names alphanumericfunid functor names alphanumeric

Long identifiers

longX ::= X | strid1.· · ·.stridn.X

171& %

Page 173: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

Core MLの文法規則

補助規則:

xSeq ::= x one lement| empty sequence| (x1,· · ·,xn) finite sequence(n ≥ 2)

172& %

Page 174: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

式の文法exp ::= infix

| exp : ty| exp andalso exp| exp orelse exp| exp handle match| raise exp| if exp then exp else exp| while exp do exp| case exp of match| fn match

match ::= mrule 〈| match〉mrule ::= pat => exp

173& %

Page 175: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

関数適用と中置演算子式appexp ::= atexp

| appexp atexp (left associative)infix ::= appexp

| infix vid infix

174& %

Page 176: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

原子式atexp ::= scon

| 〈op〉 longvid| {〈exprow〉 }| ()

| (exp1,· · ·,expn)

| [exp1,· · ·,expn]

| (exp1;· · ·;expn)

| let dec in exp1;· · ·;expn end

| (exp)exprow ::= lab = exp 〈, exprow〉

175& %

Page 177: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $パターン

atpat ::= scon| 〈op〉 longvid| {〈patrow〉 }| ()

| (pat1,· · ·,patn)| [pat1,· · ·,patn]| (pat)

patrow ::= ...

| lab = pat 〈, patrow〉| vid〈:ty〉 〈as pat〉 〈,patrow〉

pat ::= atpat| 〈op〉 longvid atpat| pat vid pat| pat : ty| 〈op〉 pat 〈: ty〉 as pat

176& %

Page 178: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

型ty ::= tyvar

| {〈tyrow〉}| tySeq longtycon| ty1 * · · · * tyn

| ty -> ty| (ty )

tyraw ::= lab : 〈, tyraw〉

177& %

Page 179: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

宣言 (1)

dec ::= val tyvarSeq valbind| fun tyvarSeq funbind| type tybind| datatype datbind 〈withtyp tybind〉| datatype tycon = longtycon| exception exbind| local dec in dec end

| opne longstrid1 · · · longstridn

| dec ; dec| infix 〈d〉 vid1 · · · vidn

| infixr 〈d〉 vid1 · · · vidn

| nonfix vid1 · · · vidn

valbind ::= pat = exp 〈and valbind〉| rec valbind

178& %

Page 180: プログラミング言語Standard ML — Introduction to …...MLの教科書 Our lecture will roughly be based on プログラミング言語Standard ML入門,大堀淳,共立出版.

' $

宣言 (2)

funbind ::= 〈op〉 vid atpat11 · · · atpat1n 〈: ty〉 = exp1 (m,n ≥ 1)| 〈op〉 vid atpat21 · · · atpat2n 〈: ty〉 = exp2| · · ·| 〈op〉 vid atpatm1 · · · atpatmn 〈: ty〉 = expm

tybind ::= tyvarSeq tycon = ty 〈and tybind〉datbind ::= tyvarSeq tycon = conbind 〈and datbind〉conbind ::= 〈op〉 vid 〈of ty〉 〈| conbind〉exbind ::= 〈op〉 vid 〈of ty〉 〈and exbind〉

| 〈op〉 vid = 〈op〉 lognvid 〈and exbind〉

179& %