Haskell递归“:”替换为||为什么?

时间:2012-10-25 22:57:06

标签: haskell recursion

我有一个问题,为什么这个函数不能与“:”一起使用,但与||一起使用为什么“:”被||取代 我的意思是为什么不能写

包含xs(y:ys)=前缀xs(y:ys):包含xs ys

 contains :: String -> String -> Bool
 contains [] _ = True
 contains _ [] = False
 contains xs (y:ys) = prefix xs (y:ys) || contains xs ys

1 个答案:

答案 0 :(得分:9)

关键想法

使用:建立列表答案,||&&以构建真/假答案,并+*构建一个数字答案。想想你要合并的东西 - 它不一定是:

<强>详细

我认为你的意思是问为什么你不能写

contains xs (y:ys) = prefix xs (y:ys)  :  contains xs ys

:用于将元素粘贴到列表的前面,因此它具有类型a -> [a] -> [a]。这意味着您在左侧放置一个东西,在右侧放置一个列表。您经常在编写递归函数时使用它,例如,您可以定义

increase :: [Int] -> [Int]
increase [] = []
increase (x:xs) = x + 5 : increase xs

此处x + 5Intincrease xs[Int]

让我们来看看你的功能。它的类型是contains :: String -> String -> Bool所以它需要一个String,然后是一个String,然后给你一个Bool。直到=获得prefix xs (y:ys)之后。现在prefix具有相同的类型:prefix :: String -> String -> Bool,所以现在我们已经给它xs(y:ys)它给了我们一个Bool。

在该行的最后,我们也得到了contains xs ys,这也是一个Bool,所以如果我们将:放在它们之间,我们就有点像

False : True

但我们不允许这样做,因为True不是列表。 (请记住(:) :: a -> [a] -> [a]。)您可以执行False:[True][False,True],但这不是您想要的。

您需要检查xs是否存在 - 稍后在(y:ys) 的前面。 的符号为||。所以代码说

  

xs位于(y:ys),如果它位于prefix xs (y:ys)的前面,或者它位于ys的某个位置(contains xs ys }})。

使用:(符号前置),它会说

  

xs位于(y:ys),如果它位于其前面(prefix xs (y:ys)),请将答案放在这些答案前面 - 它位于某处yscontains xs ys)。

没有意义。这就是您需要或(||)不在前面(:)的原因。