我在 Haskell 中创建了一个二叉树数据类型,根据以下代码:
data Tree a = EmptyTree
| Node a
(Tree a) (Tree a) deriving (Show,Eq)
我还创建了一个函数来在树中插入元素:
treeinsert :: (Ord a) => a -> Tree a -> Tree a
treeinsert x EmptyTree = leaf x
treeinsert x (Node a left right)
| x == a = Node x left right
| x < a = Node a (treeinsert x left) right
| x > a = Node a left (treeinsert x right)
现在,为了进行测试,我正在使用 Int 元素列表,如下所示:
ghci> let nums = [8,6,4,1,7,3,5]
ghci> let numsTree = foldr treeInsert EmptyTree nums
ghci> numsTree
Node 5 (Node 3 (Node 1 EmptyTree EmptyTree) (Node 4 EmptyTree EmptyTree)) (Node 7 (Node 6 EmptyTree EmptyTree) (Node 8 EmptyTree EmptyTree))
我的问题是当我检查 numsTree 的类型时:
:type numsTree
numsTree :: Tree Integer
为什么它不只有"树"的类型?
我有点困惑。(对不起我的语言(
您将类型Tree
定义为参数化类型。 数据类型定义中Tree
之后的a
是此参数。 这意味着不仅有一种Tree
类型,而且有许多不同的类型。 例如,可以有一个包含整数的类型Tree Integer
、一个包含布尔值的类型Tree Bool
和一个包含字符串到字符串的函数的类型Tree (String -> String)
。
请注意,您可以区分这些不同的类型是一件好事。 这意味着当你从这样的树中得到一个值时,你知道你将得到哪种类型的值。 如果只有一种Tree
类型,那么您将无法找到。
为什么它不只有"树"的类型?
因为您显式地将数字列表传递给它,从而限制类型。
如果您定义nTree = foldr treeInsert
(在 ghci 中预置一个let
(,您将获得预期的更通用的类型。顺便说一下,您可能希望将Leaf a
添加为另一个数据构造函数。