如何为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 我了解如何获取这种类型,但不太确定如何绘制解析树来表示它 在我的家庭作业中,我们做了这样一个简单的问题: 我能想到的最简单的方法是稍微重新格式化代

因此,我正在进行练习期末考试,有一个问题要求我为这个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 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
,因为我们要返回