Haskell 检查数字是否在树中的函数
我想写一个小程序,可以检查给定的数字是否出现在树上。这是我的代码:Haskell 检查数字是否在树中的函数,haskell,Haskell,我想写一个小程序,可以检查给定的数字是否出现在树上。这是我的代码: import Prelude data Tree = Node Int [Tree] Tree happytree = Node 5 [Node 1 [Node 6 []],Node 8 [],Node 2 [Node 1 [],Node 4 []]] contains1 :: [Tree] -> Int -> Bool contains1 [] x = False contains1 (a:as) x = c
import Prelude
data Tree = Node Int [Tree]
Tree happytree = Node 5 [Node 1 [Node 6 []],Node 8 [],Node 2 [Node 1 [],Node 4 []]]
contains1 :: [Tree] -> Int -> Bool
contains1 [] x = False
contains1 (a:as) x = contains a x || contains1 as x
contains :: Tree -> Int -> Bool
contains (Node x []) y = x==y
contains (Node x as) y = x==y || contains1 as y
我收到了错误信息
Not in scope: data constructor ‘Tree’
Perhaps you meant ‘True’ (imported from Prelude)
这是什么意思?
我想知道是否有人能给我一个建议,如何在不编写帮助函数contains1的情况下编写contains函数
提前感谢您从声明
树happytree=…
中得到错误。代码中似乎潜入了一种C风格的习惯,而您试图以错误的方式用类型声明常量
它只是happytree=…
,编译器推断出类型。如果要显式地指定它,可以像使用函数一样,在单独的一行中编写happytree::Tree
至于去除contains1
,它正在测试列表中的任何树是否包含该值,因此您可以通过以下方式去除该值:
contains :: Tree -> Int -> Bool
contains (Node x []) y = x==y
contains (Node x as) y = x==y || any (`contains` y) as
我在这里使用部分应用的
包含的节语法;您可以改为编写一个lambda\a->包含一个y
,而Sebastian的回答告诉您问题所在(类型声明属于它们自己的行),请注意,错误消息来自以下方面:
data Id Int = Id Int
Id x = Id 5
这是完全有效的,因为您使用的是模式idx
。类似于
(x:_) = [5..]
但是,为了做到这一点,您需要一个数据构造函数,例如可以创建值的东西,如节点
,而树
是一个类型构造函数,它创建(或在本例中是)类型。这就是为什么您最终会收到一条相当神秘的错误消息:
无论哪种方式,您都可以通过从Tree happytree
中删除Tree
来修复此问题
对于其他问题,请使用any
:
contains :: Tree -> Int -> Bool
contains (Node x as) y = x == y || any (`contains` y) as
请注意,类elem
的函数(在列表elem::Eq a=>a->[a]->Bool
中)通常首先使用谓词,最后使用容器,这使得包含的应用程序更容易:
contains :: Int -> Tree -> Bool
contains y (Node x as) = x == y || any (contains y) as
当您编写Tree happytree
时,您是指happytree::Tree
并在单独的一行happytree=…
?为什么要在happytree
定义的左侧使用类型构造函数Tree
?您可能指的是happytree::Tree;happytree=Node…
。是的,谢谢!我非常确定我总是这样声明我的变量^^我编辑了这个问题。每个帖子一个问题,并且不会显著改变你的问题。否则答案将不同步(请参阅Sebastian答案的开头,以及我的答案)。顺便说一句,如果你有工作代码,并且你想知道如何更好地编写它,或者它是好的还是坏的做法,请访问。好的,我将把它更改回来,感谢链接。你甚至可以使包含更容易,因为任何都会在空列表中返回False
。这比原始算法快吗?因为在我看来,any所做的或多或少与contains1函数相同。它所做的与contains1
函数完全相同,它只是用高阶函数any
替换显式递归。除非你的树有特殊的属性,比如键被排序,否则没有办法使它比这种蛮力方法更快。@SebastianRedl我不会称之为蛮力。这只是一个线性搜索。
contains :: Int -> Tree -> Bool
contains y (Node x as) = x == y || any (contains y) as