haskell - 理解“约束中的非类型变量参数”
问题描述
我想将我写的 trie 数据类型转换为Data.Tree.Tree
我的 trie 类型如下所示:
import qualified Data.Map as DM
data Trie a = Node {
label :: a,
edges :: DM.Map a (Trie a),
isFinal :: Bool
}
现在我写了这个函数进行转换:
import qualified Data.Tree as DT
toDataTree :: (Eq a, Eq (Trie a)) => Trie a -> DT.Tree a
toDataTree (Node label edges isFinal)
| edges == DM.empty = DT.Node label (map toDataTree (DM.elems edges))
| otherwise = DT.Node label []
但它不编译。我正进入(状态
• Non type-variable argument in the constraint: Eq (Trie a)
(Use FlexibleContexts to permit this)
• In the type signature:
toDataTree :: (Eq a, Eq (Trie a)) => Trie a -> DT.Tree a
|
19 | toDataTree :: (Eq a, Eq (Trie a)) => Trie a -> DT.Tree a
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Failed, no modules loaded.
据我所知,我不明白该错误消息和我在谷歌搜索错误时发现的其他问题并不能真正转移到我的代码中。
在这种情况下,该错误是什么意思,是什么原因造成的?
解决方案
在普通的 Haskell 2010 中,约束只能应用于类型变量,比如a
orb
或其他,但不能应用于更复杂的东西。
合法的:Show a => a -> String
非法的:Show (Maybe a) => a -> String
在此示例中,Show (Maybe a)
约束是非法的,因为Maybe a
它不是类型变量。a
是一个类型变量,但Maybe a
不是。
在您的代码中,编译器抱怨这Trie a
不是约束中的类型变量Eq (Trie a)
。
由于不允许这样的约束没有合理的技术理由,除了它更难实现之外,FlexibleContexts
引入了一个名为的扩展(参见docs),使这样的约束合法。这就是编译器告诉你的。您可以打开此扩展程序,它没有任何缺点。
推荐阅读
- python - 两个值匹配 pandas 时的累积计数
- mongodb - 如何在 Spring Boot 的响应式 mongodb 客户端中启用 ssl?
- mysql - MySQL数据库离线到在线同步
- java - 使用 Mockito2 在 java 中模拟本地创建的对象
- python-3.x - 无法在 python3 中导入 numpy
- python - Python 读取 YAML:哪里出错了:使用 open() 还是 yaml.load()?
- css - 接收样式并将其动态应用到使用类选择的元素,使用 Vue
- amazon-athena - Presto - 减少结构数组
- javascript - Angular 6 [ngClass] 不适用于 component.js 中的布尔值
- javascript - 如何使用 JavaScript 将 windows SYSTEMTIME 转换为 Unix?