Learn You a Haskell 创建一个 Tree
代数数据类型:data Tree a = EmptyTree | Node a (Tree a) (Tree a) deriving (Show, Read, Eq)
我的理解是 a
可以是任何类型。
因此,我尝试创建一个 treeInsert
函数,根据其 Tree
值将 Side
放在左侧或右侧:
data Side = L | R
singletonTree :: a -> Tree a
singletonTree x = Node x EmptyTree EmptyTree
treeInsert :: a -> Tree a -> Tree a
treeInsert x EmptyTree = singletonTree x
treeInsert x@(L, _) (Node a left right) = Node a (treeInsert x left) right -- ERROR
treeInsert x@(R, _) (Node a left right) = Node a left (treeInsert x right)
但是我得到了一个编译时错误:
Couldn't match expected type `a' with actual type `(Side, t0)'
`a' is a rigid type variable bound by
the type signature for treeInsert :: a -> Tree a -> Tree a
at File.hs:10:15
In the pattern: (L, _)
In an equation for `treeInsert':
treeInsert x@(L, _) (Node a left right)
= Node a (treeInsert x left) right
Failed, modules loaded: none.
也许
a
仍然是任何类型,但我的模式匹配无效? 最佳答案
仅仅因为 a
通常可以是 Tree a
中的任何类型,并不意味着它可以是传递给 treeInsert
的树中的任何类型。您需要将其细化为实际允许 (L, _)
和 (R, _)
模式匹配的类型。
实际上,您可以删除 treeInsert
上的类型注释,它会编译,之后您可以使用 :t
向 GHCi 询问正确的类型(如果需要,然后重新添加该注释):
treeInsert :: (Side, t) -> Tree (Side, t) -> Tree (Side, t)
关于Haskell 类型变量,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24543888/