出于教育目的,我正在使用Haskell玩弄树。 我定义了像这样的Tree a
类型
data Tree a = EmptyTree | Node a (Tree a) (Tree a)
许多函数都有一个共同的基本约束条件 - Ord a
,因此它们的类型看起来像:
treeInsert :: Ord a => a -> Tree a -> Tree a
treeMake :: Ord a => [a] -> Tree a
等等,我也可以像这样定义Tree a
data Ord a => Tree a = EmptyTree | Node a (Tree a) (Tree a)
但我无法简化我的函数并省略额外的 Ord a
,使其如下所示:
treeInsert :: a -> Tree a -> Tree a
treeMake :: [a] -> Tree a
为什么 Haskell(使用 -XDatatypeContexts
)不能自动推断这个约束?我认为它应该很明显。我错了吗?
下面是一些示例源代码:
data (Eq a, Ord a) => Tree a = EmptyTree | Node a (Tree a) (Tree a)
treeInsert :: a -> Tree a -> Tree a
treeInsert a EmptyTree = Node a EmptyTree EmptyTree
treeInsert a node@(Node v left right)
| a == v = node
| a > v = Node v left (treeInsert a right)
| a < v = Node v (treeInsert a left) right
mkTree :: [a] -> Tree a
mkTree [] = EmptyTree
mkTree (x:xs) = treeInsert x (mkTree xs)
我遇到了这个问题
Tree.hs:5:26:
No instance for (Ord a)
arising from a use of `Node'
In the expression: Node a EmptyTree EmptyTree
In an equation for `treeInsert':
treeInsert a EmptyTree = Node a EmptyTree EmptyTree
Failed, modules loaded: none.
Eq
和Ord
都是不必要的。Eq
是Ord
的超类,因此后者已经足够了。 - augustss