检查数字是否在树中的函数

时间:2016-05-02 09:21:23

标签: 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 = 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。

提前致谢

2 个答案:

答案 0 :(得分:6)

您从声明Tree 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

我在这里使用部分语法来部分应用contains;你可以改为写一个lambda \a -> contains a y

答案 1 :(得分:6)

虽然Sebastian的回答告诉您问题(类型声明属于他们自己的行),但请注意错误消息源于以下内容:

data Id Int = Id Int

Id x = Id 5

这完全有效,因为您使用模式Id x进行绑定。它与

类似
(x:_) = [5..]

但是,为了做到这一点,你需要一个数据构造函数,例如可以创建值的内容,例如Node,而Tree类型的构造函数,它会创建(或者在本例中为)类型。这就是为什么你最终得到这个相当神秘的错误信息的原因:

Not in scope: data constructor ‘Tree’
Perhaps you meant ‘True’ (imported from Prelude)

无论哪种方式,您都可以通过从Tree移除Tree happytree来解决此问题。

对于您的其他问题,请使用any

contains :: Tree -> Int -> Bool
contains (Node x as) y = x == y || any (`contains` y) as

请注意,elem - 类似函数(在列表elem :: Eq a => a -> [a] -> Bool上)通常首先使用谓词,最后使用容器,这使contains的应用更容易:

contains :: Int -> Tree -> Bool
contains y (Node x as) = x == y || any (contains y) as
相关问题