如何为sml绘制类型推断解析树
因此,我正在进行练习期末考试,有一个问题要求我为这个sml代码绘制一个解析树:如何为sml绘制类型推断解析树,sml,Sml,因此,我正在进行练习期末考试,有一个问题要求我为这个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 我了解如何获取这种类型,但不太确定如何绘制解析树来表示它 在我的家庭作业中,我们做了这样一个简单的问题: 我能想到的最简单的方法是稍微重新格式化代
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
我了解如何获取这种类型,但不太确定如何绘制解析树来表示它
在我的家庭作业中,我们做了这样一个简单的问题:
我能想到的最简单的方法是稍微重新格式化代码,基本上将每个子表达式放在自己的行上。儿童用增加的缩进表示 让我们以你为例:
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")
现在,让我们将每个子表达式放在它自己的行上(在这个特定的示例中,这些偏执是多余的;没有它们,一切都可以正常工作):
最后,让我们为每个子表达式附加一个类型,但是让我们为我们还不知道的类型使用类型变量。注意,我们对相同的事件使用相同的类型变量。例如,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
:
fxy
F2Y
fx“零”
x
必须是int
类型,y
必须是string
类型。因此,让我们用int
替换x
的类型,即t3
,用string
替换y
的类型,即t5
。我们在任何地方都这样做:
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
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
此外,f
用作每次传递int
的函数。结果还用作函数,并传递一个字符串。这意味着分配给f
的类型变量t1
,必须是int->string->r0
类型,对于一些r0
,我们还不知道。让我们用int->string->r0
替换所有出现的t1
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
,因为fxy
的结果用于if
表达式的条件部分,所以让我们将r0
替换为bool
:
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
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
类型,因为f3y
和fx“零”
的类型都是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
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
接下来,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) -> 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
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
最后,ff
的类型t0
必须与分配给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
这就是您的最终结果。我能想到的最简单的方法是稍微重新格式化代码,基本上将每个子表达式放在自己的行上。儿童用增加的缩进表示
让我们以你为例:
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")
现在,让我们将每个子表达式放在它自己的行上(在这个特定的示例中,这些偏执是多余的;没有它们,一切都可以正常工作):
最后,让我们为每个子表达式附加一个类型,但是让我们为我们还不知道的类型使用类型变量。注意,我们对相同的事件使用相同的类型变量。例如,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
:
fxy
F2Y
fx“零”
我们可以推断,x
必须是int
类型,y
必须是string
类型。因此,让我们用int
替换x
的类型,即t3
,用string
替换y
的类型,即t5
。我们在任何地方都这样做:
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
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
此外,f
用作每次传递int
的函数。结果还用作函数,并传递一个字符串。这意味着分配给f
的类型变量t1
,必须是int->string->r0
类型,对于一些r0
,我们还不知道。让我们用int->string->r0
替换所有出现的t1
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
,因为fxy
的结果用于if
表达式的条件部分,所以让我们将r0
替换为bool
:
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
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
类型,因为f3y
和fx“零”
的类型都是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
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
接下来,t6
也必须是一个bool
,因为我们要返回