variable binding: val x = e
val:
keyword
x:
variable
e:
expression
v:
value(不需要做多余计算的表达式)
t:
type
function binding: fun x0(x1: t1, x2: t2...) = e
typing:
static environment of e: 在之前的静态环境的基础上加上:x1:t1, x2:t2..., x0: t1 * t2 *... -> t。x0在上下文中,可以用于递归。
函数x0的类型是 参数类型->结果类型,参数类型以*分开,结果类型是e的类型t。t并没有显示定义,而是由
type-checker决定的,称为类型推断
(type-inference)
after static environment: 之前的静态环境加上了x0的类型,参数的类型不再top-level静态环境中,只在函数体e中。
evaluation:
after dynamic environment/dynamic environment of e: 之前的动态环境加上了x0,供以后调用。
函数也是值
函数如果有if语句,必须保证值是同一类型的
function call: e0(e1, e2..)
typing: e0的类型是t1 * t2 *...->t, ei的类型是ti。整个调用的类型是t
evaluation:使用
调用函数的上下文求出ei的值vi,并且使用
函数定义时的上下文+vi的值得到函数调用的结果
函数求值的时候,使用个的上下文是函数定义的时候的上下文,而不是函数调用时候的上下文
anonymous function:fn x => 3 * x
通常作为参数,只是一个值,可以放在任何可以放expression的地方
不能递归
fun f1 x = 3 * x 等价于 val f1 = fn x => 3 * x
datatype binding: datatype t0 = C1 of t1 | C2 of t2 | C3...
one-of type
x1, x2是
constructors,可以得知t0的类型。
constructor是:1. 创建一个新类型的函数 (C1 of t1) t1->t0
2. 一个新类型的值 (C3) t0
evaluation:加入了新的类型t0,若干个constructors xi
创建t0: 使用constructor + 对应的expression, 会以tag的形式存储变量的类型
求类型:case expression,也叫做pattern-matching
ti也可以是t0, self-reference,可以实现递归类型,也可对应case expression实现
递归函数
语法糖:list type, option type...等等也是 datatype,也能用case expression
[option] SOME和NONE是constructors
[list] []和x::xs也是constructors
多态datatype: datatype 'a t0 = C1 of 'a| C2
能够存所有类型。并不是在环境中加入了t0这个类型,而是如果存在t这个类型,则存在t t0这个类型