当前位置: 首页 > 知识库问答 >
问题:

具有可变成员的树上的Haskell树foldt

弓嘉纳
2023-03-14

我试图创建一个自定义数据类型树。定义如下:

树可以定义为包含一条信息(即,它是一个没有子节点的节点)的叶(由关键字“叶”标识),或包含一条信息的节点(由关键字“节点”标识),再加上树列表–列表中的每个元素表示根在相应子节点上的子树。请注意,根据此定义,树永远不能为空。这意味着树可以是:

  • 叶片数据;或

这是我的代码:

data Tree a = Leaf a | Node a [ Tree a ] deriving (Show)

foldt :: (a -> a -> a) -> Tree a -> a
foldt f (Leaf a)     = a
foldt f (Node a [])  = a
foldt f (Node a [b]) = f a (foldt f b)

它可以编译,但当我尝试运行时:

let myTree = Node 'A' [Node 'B' [Leaf 'E', Node 'F' [Leaf 'I', Leaf 'J', Leaf 'K']], Node 'C' [Leaf 'G', Leaf 'H'], Leaf 'D']
foldt min myTree

而不是预期的输出'A',我得到以下错误:

CSC207a4.hs:(6,1)-(8,38): Non-exhaustive patterns in function foldt

我的函数的哪一部分不是详尽的,或者我定义的数据类型不正确?

更新:

我可能已经解决了非穷举模式,我现在有了这个,但它声称树没有定义:

数据树a=叶a|节点a[树a]派生(显示)

foldt :: (a -> a -> a) -> Tree a -> a
foldt f (Leaf a)     = a
foldt f (Node a [])  = a
foldt f (Node a [(Tree x)])  = f a (foldt f x)
foldt f (Node a [(Tree x):xs]) = f a (foldt f (f x (foldt f xs)))

共有2个答案

乌骏
2023-03-14

我已经找到了答案。熬夜一整夜后,我突然有了灵感。这里是:

module CSC207a4 where

data Tree a = Leaf a | Node a [ Tree a ] deriving (Show)

foldt :: (a -> a -> a) -> Tree a -> a
foldt _ (Leaf a)    = a
foldt _ (Node a []) = a
foldt f (Node a b)  = f (foldt f x) (foldt f (Node a xs))
    where
        x:xs = b

这通过了所有测试用例,回答了我的问题。

蓬兴国
2023-03-14

通过打开警告,您可以从GHC获得一些帮助。“大锤”是-Wall

-- At the very top of the file
{-# OPTIONS_GHC -Wall #-}

噪音较小的方法也适用:

{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}

这两个选项中的任何一个都将为您提供编译时未能匹配的模式的显式列表。

Tree放在模式中不起作用的原因是Tree是一个类型构造函数(通过将它们放在datanewtype声明的左侧进行排序)。只有数据构造函数(将它们放在datanewtype声明的右侧进行排序)才能在模式中匹配。

 类似资料:
  • Haskell库中是否存在这种数据结构?我做了一些搜索,但找不到任何有用的东西。我想使用现有的类型,而不是定义我自己的类型——它似乎应该存在。 这个想法是它与Data. Tree非常相似,但是边可以保存信息和节点。 如果你有一个通过树的路径(类型为[e]),你可以在O(log(n))中找到rootLabel(类型为n)。据我所知,你不能用Data做这件事。树,因为您必须扫描每个节点的子节点,以查找

  • 我想出了这个类: 这里是用法: 问题: 为什么使用作为返回表达式编译得很好(Z不是instexpr)。 如何调用和方法的对象() ? 中的行为在编译器中是不同的。MSVC可以使用作为模板参数进行编译,而GCC(IdeOne)不会编译它。 对于一个编译器来说< code>constexpr GetX是真正的< code>constexpr,但是对于另一个编译器来说,如果涉及到< code>X Z就不

  • 我希望生成一个可视化xml文件结构的图形。 我创建了一个节点列表来表示xml文件 每个节点包含3个字符串:xml标记、属性和内容。 xml 文件如下所示: 我希望通过枚举节点列表,使用Plotly和igraph库生成一个树形图。 我在这里使用这个网站作为参考。 我的XML文件包含子元素数量可变的元素。然而,给出的例子只向我展示了如何开发一个具有固定数量的子节点的树(这个例子展示了每个节点2个子节点

  • 我目前正在尝试遍历二叉树以检查某些值是否在其中。for 循环正在测试 1 到 50 之间的所有值,并将为每个匹配的值返回 true。 这是当前的树: 现在我必须实现成员函数,我有正确的想法下来,但它在检查根后停止,根 - 前面所述的for循环打印输出 但仅此而已。 有人会通过伪代码或脚本提供一些方向吗?你不必给我代码,因为我想自己弄清楚。谢谢。

  • 问题内容: 在研究一个简单的HTMLElement包装器的想法时,我偶然发现了Internet Explorer和Chrome的以下内容: 对于DOM树中具有ID的给定HTMLElement,可以使用其ID作为变量名来检索div。所以对于像 在Internet Explorer 8 和Chrome中,您可以执行以下操作: 要么 那么,这是否意味着 DOM树中的每个元素都将 转换为全局名称空间中的变

  • 我一直在读生成树的概念及其类型。这就是我所理解的: 生成树:图G中连接所有顶点的边数最小的子集 最小生成树:它是边权的总和最小的生成树。 现在,这是否意味着,在检索MST时, > 如果我们遇到G中的一条路径,它有更多的边(与其他路径相比),但在边权重总和上的权重最小(与所有其他路径相比),我们将不把它视为MST? MST的概念是否只有在G有多个生成树的情况下才起作用?其他跨树=mst? 谢谢你的帮