在SML中为环境创建函数表示

在SML中为环境创建函数表示,sml,Sml,好的,我正在为SML中的环境创建函数表示: type name = string type 'a fenv = name -> 'a 我对如何继续这件事有点困惑。我需要做的第一件事是定义类型为'a fenv'的值fenvEmpty,它表示空环境(不绑定任何名称的环境)。到目前为止,我有: val fenvEmpty = let fun empty (name) = ??? in empty end 我不确定我是否在正确的轨道上。

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

type name = string
type 'a fenv = name -> 'a
我对如何继续这件事有点困惑。我需要做的第一件事是定义类型为'a fenv'的值fenvEmpty,它表示空环境(不绑定任何名称的环境)。到目前为止,我有:

val fenvEmpty = 
    let
        fun empty (name) = ???
    in
        empty
    end
我不确定我是否在正确的轨道上。我应该从函数empty返回什么?输入0、null或NONE将不起作用


稍后,我还必须编写返回与环境中特定名称关联的数据的函数(find函数),以及将数据绑定到环境中特定名称的函数(bind函数),但是我已经被困在了芬维特部分。

我想老师希望你在试图查找未绑定值时提出一个异常:

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

exception UnboundName of name

fun fenvEmpty name = raise UnboundName name
但我认为,如果您首先尝试使用一个版本的
fenv
,该版本对未绑定变量返回
NONE
,将对您帮助更大。我相信这是因为,与异常相反,程序有更多的类型结构,可以在编写实现时指导您(另请参见下文)。因此,首先尝试编写这个实现,其中
fenv
是:

type 'a fenv = name -> 'a option
type 'a fenv = name -> 'a
现在,对于问题的后面部分,您必须定义一个函数,用于将
名称
关联到现有环境。这将是该函数的类型:

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

type 'a fenv = name -> 'a
因此,这个返回值是一个函数,需要以某种方式“记住”与其关联的
名称
。函数通常如何在定义它们的上下文中“记住”它们“看到”的东西

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

val fenvLookup : 'a fenv -> name -> 'a
同样,请记住fenv的类型:

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

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

fenv不应该有返回类型
'a选项
?不,规范要求它返回'aDo规范说明了当参数是未在环境中设置的名称时应该返回什么?它没有提到,但一位同学向我暗示,这应该引起一个例外。因此,我将其更改为值内的lambda函数,该函数引发NotFound name异常。感谢您的帮助和解释。事实证明,他确实希望引发一个异常,所以我完成了这部分。你可能是说返回一个函数闭包吗?因为当我想到绑定时,我对如何将名称和值绑定到现有环境感到困惑。@laughinglama42是的,我就是这么说的。绑定新标识符时(使用
fenvAssoc
),返回的闭包可以访问
fenvAssoc
接收的名称和值。它还可以访问以前的环境。因此,稍后,当有时调用此闭包时,它可以做两件事:1)验证它得到的名称是否与它在闭包中的名称一致,或2)将此检查委托给前一个闭包。这是一堆闭包。这有意义吗?是的,谢谢你的重述,尤其是在这样一篇老文章上