gpt4 book ai didi

Haskell:Map.empty 出现 "Qualified name in binding position"错误

转载 作者:行者123 更新时间:2023-12-02 07:21:34 26 4
gpt4 key购买 nike

我正在尝试使用空 map 为新类型创建模式同义词。

{-# Language PatternSynonyms #-}

import qualified Data.Map as Map

newtype StoreEnv = StoreEnv (Map.Map Int String)
deriving (Eq, Show)

pattern EmptyStore :: StoreEnv
pattern EmptyStore = StoreEnv Map.empty

编译时出现错误“绑定(bind)位置的限定名称:Map.empty”。我相信“Map.empty”应该属于我在新类型中声明的“Map.Map Int String”类型。

我的问题是是否有办法正确地为空 map 添加别名。

如有任何反馈,我将不胜感激。

最佳答案

背景

So you cannot pattern match against maps like you would do with list then.

没错。 Data.Map.Mapabstract data type ,这意味着它的表示是隐藏的。在 Haskell 中,这意味着它的构造函数不会被导出。您无法编写检查 balanced binary search tree 的代码在 Map 内部(无论如何你都不想这样做) - 你必须通过它的公共(public)接口(interface),使用模块的导出函数来创建、查询和操作 Map .

模式同义词的存在是为了弥补 ADT 编程与方程左侧模式匹配的便捷语法之间的差距。您可以将一些智能模式定义为模块 API 的一部分,而不必将 ADT 的实现耦合到这些模式。

你的问题

您会收到该错误,因为从语法上讲,模式同义词的右侧必须是模式,而不是表达式。模式(通常)是应用于某些变量绑定(bind)器的值构造函数的名称 - 也就是说,在像

这样的定义中
getBar (Foo bar baz) = bar

左侧的barbaz定义了右侧范围内的变量。它们是新的绑定(bind),而不是对可能存在于某些外部作用域中的任何 barbaz 变量的引用。

所以我认为除了语法错误(Map.empty 不是局部变量的有效名称,这就是您收到该错误的原因)之外,您还犯了一个合乎逻辑的 - 无论如何你都无法在该位置引用 Map.empty

修复

正如我在my comment中建议的那样,您可以使用explicitly bidirectional pattern synonym来修补您的代码。这是一个巧妙的功能,它允许您为模式同义词赋予不同的含义,具体取决于它是用作模式(即在模式上下文中)还是用作值构造函数(即在表达式上下文中)。

pattern EmptyStore <- StoreEnv (Map.null -> True)
where EmptyStore = StoreEnv Map.empty

在第一行中,我定义了 EmptyStore 用作模式时的含义。 Map.null -> True 语法称为 View 模式 - 它的意思是“将函数Map.null应用到模式的这一部分,并将其结果与”。因此,当 StoreEnv 内的 Map 为空时,EmptyStore 会匹配 StoreEnv

第二行定义了EmptyStore用作表达式时的作用。它表示表达式 EmptyStore 是表达式 StoreEnv Map.empty 的同义词 - “创建一个空的 Map 并将其包装在 >StoreEnv”。

取消修复

但是我认为 Map 的模式同义词 API 并没有真正的意义。为了可用,您应该真正定义一套完整模式,以便用户能够解构任何类型的Map。空的情况很容易处理,因为只有一个空的 Map,但是在非空的 Map 上进行模式匹配意味着什么? Map 并不意味着是有序的容器 - 没有像 [] 那样的“首先和其余”,所以这是没有意义的:

pattern Cons k v rest <- {- what goes here? -}
where Cons k v rest = insert k v rest

您可以尝试定义一个模式,本地图中存在特定键时进行匹配:

pattern Contains k v <- (lookup k -> Just v)

但这不是有效的 Haskell(k引用,而它应该绑定(bind))。即使您能想出一种巧妙的方式来表达它,这样的一组模式也必然是不完整的,因为您无法为每个可能的键编写子句。

换句话说,我认为您不应该尝试为此数据类型定义模式同义词。坚持使用普通功能!

关于Haskell:Map.empty 出现 "Qualified name in binding position"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49845591/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com