从THIH中理解修改函数(在Haskell中键入Haskell)



我正在阅读在haskell 中键入haskell的文章

很难理解p13 上的这行编码

modify ce i c = ce{classes=j→if I==j then Just c else classes ce j}

j从哪里来?在第13页上有一个关于修改的简短覆盖,但根本没有提到j。在p14上,有一个对addClass下的return(modify ce i(is,[]((的调用。这是我想不通的地方。如果没有提供j,如何调用修改ce i(is,[](?谢谢你的帮助。

j仍然是lambda表达式的一部分

j -> if i==j then Just c else classes ce j

其定义CCD_ 2字段的值。此函数是modify本身作为参数接收的值icce的闭包。

这就像一个递归函数:modify ce i c的结果是一个值,其中(对于某些值ceicx(

classes (modify ce i c i) == Just c

classes (modify ce i c x) == classes ce x`.

除了classes实际调用自身之外,modify创建了一个类型为ClassEnv的新值,该值封装了一个"0";较小的";相同类型的值。classes函数一次打开该环境一层,直到找到原始参数的匹配值,或者达到classes initalEnv _ == Nothing所对应的initialEnv值。

j是lambda参数。您可以为参数指定任何您喜欢的名称。它代表什么?modify的类型签名告诉我们第一个参数的类型是classes0,所以您可以阅读其定义(第12页(,看看其classes字段的类型。

为了补充其他答案,该论文的作者只使用函数定义了一个非常简单的地图或字典。通常,您可以编写Map Id Class,其中Map来自containers包,但您也可以使用类型Id -> Maybe Class,它基本上是映射类型的lookup函数。然后可以像这样实现一些简单的功能:

type Map k v = k -> Maybe v
singleton :: Eq k => k -> v -> Map k v
singleton k v = k' -> if k == k' then Just v else Nothing
insert :: Eq k => k -> v -> Map k v -> Map k v
insert k v lookup = k' -> if k' == k then Just v else lookup k'
union :: Map k v -> Map k v -> Map k v
union lookup1 lookup2 = k -> case lookup1 k of
Nothing -> lookup2 k
v -> v
delete :: Eq k => k -> Map k v -> Map k v
delete k lookup = k' -> if k == k' then Nothing else lookup k'
lookup :: Map k v -> k -> Maybe v
lookup = id

因此,不是将映射定义为值的集合,而是将映射定义成查找函数。

这种方法的一个优点是它很简单,因为它不依赖于外部依赖关系。但它并没有那么灵活:例如,你不能列出地图中的所有键和值;而且它很慢:查找需要进行线性数量的相等性测试。

最新更新