对 Haskell 中 Int 节点的二叉树数据类型的实例类型感到困惑



我在 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添加为另一个数据构造函数。

最新更新