【问题标题】:Creating a Function Representation for Environments in SML在 SML 中为环境创建函数表示
【发布时间】:2015-03-17 17:22:13
【问题描述】:

好的,所以我正在为 SML 中的环境创建函数表示:

type name = string
type 'a fenv = name -> 'a

我有点不知道如何进行此操作。我需要做的第一件事是定义一个 'a fenv 类型的值 fenvEmpty,它表示空环境(不绑定任何名称的环境)。到目前为止,我有这个:

val fenvEmpty = 
    let
        fun empty (name) = ???
    in
        empty
    end

我不确定我是否走在正确的轨道上。我应该从空函数返回什么?输入 0、null 或 NONE 将不起作用。

稍后,我还必须编写返回与环境中特定名称关联的数据的函数(查找函数),以及将数据绑定到环境中特定名称的函数(绑定函数),但是我' m 已经卡在 fenvEmpty 部分了。

【问题讨论】:

  • 不应该fenv 有返回类型'a option
  • 不,规范要求它返回 'a
  • 规范是否说明了当参数是环境中未设置的名称时应返回的内容?
  • 没提,但是有同学提示我应该抛出异常。因此,我将其更改为引发 NotFound 名称异常的值内的 lambda 函数。

标签: sml


【解决方案1】:

我猜老师希望你在尝试查找未绑定值时raise 异常:

type name = string
type 'a fenv = name -> 'a

exception UnboundName of name

fun fenvEmpty name = raise UnboundName name

但我认为,如果您首先尝试使用为未绑定变量返回NONEfenv 版本,它会为您提供更多帮助。我相信这是因为,与异常相反,程序有更多的类型结构可以在编写实现时指导您(另见下文)。所以,首先尝试在fenv 所在的位置编写这个实现:

type 'a fenv = name -> 'a option

现在,对于问题的后半部分,您必须定义一个函数,用于将 namevalue 关联到现有环境。这将是该函数的类型:

val fenvAssoc : 'a fenv -> name -> 'a -> 'a fenv

请注意,上面返回的结果类型为'a fenv。但请记住 fenv 实际上是什么。它“只是”一个函数:

type 'a fenv = name -> 'a

所以,这个返回值,一个函数,需要以某种方式“记住”与之关联的namevalue。函数通常如何在定义它们的上下文中“记住”它们“看到”的东西?

要查找名称的值,您需要第三个函数,它采用现有环境和名称并返回该名称的值(如果有):

val fenvLookup : 'a fenv -> name -> 'a

再次记住'a fenv的类型是什么:

type 'a fenv = name -> 'a

我之所以强调这一点,是因为'a fenv 的类型限制了您可以对其应用的操作。您基本上可以:a)创建一个函数或 b)应用一个。

【讨论】:

  • 感谢您的帮助和解释。事实证明,他确实希望引发异常,所以我完成了那部分。
  • 你是说要返回一个函数闭包吗?因为当我想到绑定时,我对如何将名称和值绑定到现有环境感到困惑。
  • @laughingllama42 是的,这就是我要说的。绑定新标识符时(使用fenvAssoc),返回的闭包可以访问fenvAssoc 收到的名称和值。它还可以访问以前的环境。所以稍后,当有时调用这个闭包时,它可以做两件事:1)验证它在闭包中的名称,或 2)将此检查委托给前一个闭包。这是一堆闭包。这有意义吗?
  • 是的,谢谢你的重述,尤其是在这么老的帖子上
猜你喜欢
  • 2021-11-15
  • 1970-01-01
  • 2018-08-16
  • 1970-01-01
  • 2018-08-17
  • 2017-04-08
  • 2021-09-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多