所以我正在进行练习决赛,有问题请我为这个sml代码绘制一个解析树:
fun ff f x y = if (f x y) then (f 3 y) else (f x "zero")
val ff = fn : (int -> string -> bool) -> int -> string -> bool
我理解如何获得这种类型但不太确定如何绘制一个解析树来表示它。
对于我的作业,我们确实做了这样的问题,这更简单: image for my other homework
答案 0 :(得分:2)
我能想到的最简单的方法是稍微重新格式化代码,并基本上将每个子表达式放在自己的行上。儿童用增加的缩进表示。
让我们举个例子:
fun ff f x y = if (f x y) then (f 3 y) else (f x "zero")
首先,我们需要做一点点贬低。以上相当于:
val ff =
fn f =>
fn x =>
fn y =>
if (f x y) then (f 3 y) else (f x "zero")
现在,让我们将每个子表达式放在它自己的行上(在这个特定的例子中,parantheses是多余的;没有它们,一切正常):
val ff =
fn f =>
fn x =>
fn y =>
if
f
x
y
then
f
3
y
else
f
x
"zero"
最后,让我们为每个子表达式附加一个类型,但让我们使用类型变量来表示我们还不知道的类型。请注意,我们对相同的事件使用相同的类型变量。例如,x
到处都有t3
类型。
Subexpression | Type
---------------------- | ------------------------------------------
val ff = | t0
fn f => | t1 -> t2
fn x => | t3 -> t4
fn y => | t5 -> t6
if | t7 (* the type of the whole `if` expression *)
f | t1
x | t3
y | t5
then | t8 (* the type of the whole `then` part *)
f | t1
3 | int
y | t5
else | t9 (* the type of the whole `else` part *)
f | t1
x | t3
"zero" | string
然后,您可以通过注意某些类型变量是等效的或在某些上下文中使用它们来进行进一步的简化。例如,从这三次调用f
:
f x y
f 2 y
f x "zero"
我们可以收集x
必须属于int
类型且y
必须属于string
类型。因此,让我们用x
替换t3
的{{1}}类型,用int
替换y
的类型,t5
,与string
。我们到处都这样做:
Subexpression | Type
---------------------- | ------------------------------------------
val ff = | t0
fn f => | t1 -> t2
fn x => | int -> t4
fn y => | string -> t6
if | t7
f | t1
x | int
y | string
then | t8
f | t1
3 | int
y | string
else | t9
f | t1
x | int
"zero" | string
此外,f
用作每次传递int
的函数。结果也用作函数,并传递string
。这意味着t1
,即分配给f
的类型变量,必须是int -> string -> r0
类型,对于我们还不知道的某些r0
。我们将所有t1
替换为int -> string -> r0
。
Subexpression | Type
---------------------- | ------------------------------------------
val ff = | t0
fn f => | (int -> string -> r0) -> t2
fn x => | int -> t4
fn y => | string -> t6
if | t7
f | int -> string -> r0
x | int
y | string
then | t8
f | int -> string -> r0
3 | int
y | string
else | t9
f | int -> string -> r0
x | int
"zero" | string
但请注意,r0
必须被视为bool
,因为f x y
的结果用于if
表达式的条件部分,所以让&# 39; s将r0
替换为bool
无处不在:
Subexpression | Type
---------------------- | ------------------------------------------
val ff = | t0
fn f => | (int -> string -> bool) -> t2
fn x => | int -> t4
fn y => | string -> t6
if | t7
f | int -> string -> bool
x | int
y | string
then | t8
f | int -> string -> bool
3 | int
y | string
else | t9
f | int -> string -> bool
x | int
"zero" | string
接下来,整个if
表达式的类型必须与then
部分的类型相同,else
部分的类型必须与t7
部分的类型相同。因此t8
,t9
和t7
必须全部相同。让我们使用t8
我们看到t9
和Subexpression | Type
---------------------- | ------------------------------------------
val ff = | t0
fn f => | (int -> string -> bool) -> t2
fn x => | int -> t4
fn y => | string -> t6
if | t7
f | int -> string -> bool
x | int
y | string
then | t7
f | int -> string -> bool
3 | int
y | string
else | t7
f | int -> string -> bool
x | int
"zero" | string
。
t7
接下来,bool
必须是f 3 y
类型,因为f x "zero"
和bool
的类型都是Subexpression | Type
---------------------- | ------------------------------------------
val ff = | t0
fn f => | (int -> string -> bool) -> t2
fn x => | int -> t4
fn y => | string -> t6
if | bool
f | int -> string -> bool
x | int
y | string
then | bool
f | int -> string -> bool
3 | int
y | string
else | bool
f | int -> string -> bool
x | int
"zero" | string
:
t6
接下来,bool
也必须是if
,因为我们会返回Subexpression | Type
---------------------- | ------------------------------------------
val ff = | t0
fn f => | (int -> string -> bool) -> t2
fn x => | int -> t4
fn y => | string -> bool
if | bool
f | int -> string -> bool
x | int
y | string
then | bool
f | int -> string -> bool
3 | int
y | string
else | bool
f | int -> string -> bool
x | int
"zero" | string
表达式的结果:
t4
接下来,string -> bool
必须是Subexpression | Type
---------------------- | ------------------------------------------
val ff = | t0
fn f => | (int -> string -> bool) -> t2
fn x => | int -> string -> bool
fn y => | string -> bool
if | bool
f | int -> string -> bool
x | int
y | string
then | bool
f | int -> string -> bool
3 | int
y | string
else | bool
f | int -> string -> bool
x | int
"zero" | string
类型,因为它的主体类型是:
t2
int -> string -> bool
是什么?它必须是正文的类型,即Subexpression | Type
---------------------- | ------------------------------------------
val ff = | t0
fn f => | (int -> string -> bool) -> int -> string -> bool
fn x => | int -> string -> bool
fn y => | string -> bool
if | bool
f | int -> string -> bool
x | int
y | string
then | bool
f | int -> string -> bool
3 | int
y | string
else | bool
f | int -> string -> bool
x | int
"zero" | string
:
t0
最后,ff
的{{1}}类型必须与分配给ff
的值的类型相同。所以:
Subexpression | Type
---------------------- | ------------------------------------------
val ff = | (int -> string -> bool) -> int -> string -> bool
fn f => | (int -> string -> bool) -> int -> string -> bool
fn x => | int -> string -> bool
fn y => | string -> bool
if | bool
f | int -> string -> bool
x | int
y | string
then | bool
f | int -> string -> bool
3 | int
y | string
else | bool
f | int -> string -> bool
x | int
"zero" | string
这是你的最终结果。