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