モジュール間の副作用伝搬!? structure A = B は別名をつけているだけで、副作用が
伝わる。
counter.sml
moduleはデーターじゃなくってあるデータ型とそれに対する操作を定義。
状態をもっても、C++のクラス変数みたいなもので....。
letのsyntax (たぶんSMLのsyntax)
let dec in exp1; ... ; expn end
スコープの終りを示すendがある....
レコード
- - type sample = {f : int -> int};
> type sample = {f : int -> int}
- val a =
{ f =
let fun fib n =
if (n = 0 orelse n = 1) then 1
else fib(n-1) + fib(n-2) in fib end };
> val a = {f = fn} : {f : int -> int}
- #f a;
> val it = fn : int -> int
- (#f a) 10;
> val it = 89 : int
レコードのフィールド参照は #[field_name] でできる。これは関数のように
文面上は扱えるけれども関数ではない。
- #f;;
! Toplevel input:
! #f;;
! ^^
! Unresolved record pattern
{ f = v } はフィールドがfしかないレコードを表している。レコードは型の宣言を
しなくても使えるようで。f に束縛される値の型は多相でよいようで。
- fun get_f x = case x of { f = v } => v;;
> val 'a get_f = fn : {f : 'a} -> 'a
参考) Ocamlの場合
# let get_f x = match x with { f = v } -> v;;
Characters 27-36:
let get_f x = match x with { f = v } -> v;;
^^^^^^^^^
Unbound record field label f
# type 'a record = { f : 'a };;
type 'a record = { f : 'a; }
# let get_f x = match x with { f = v } -> v;;
val get_f : 'a record -> 'a = <fun>
レコードはあらかじめ型宣言しておかないと使えない。
同じのりでタプル
- #1 (1,3);
> val it = 1 : int
文法の些細な違いって結構痛い
| Ocaml | SML |
| match expr with | case expr of |