3

我有一个问题,为什么这个函数不能与“:”一起使用,但可以与 || 一起使用 以及为什么将“:”替换为|| 我的意思是为什么不能写

包含 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
4

1 回答 1

9

关键思想

用于:建立一个列表答案,||&&建立一个真/假答案,和/+*建立一个数字答案。想想你正在结合什么——它不必一直:都是。

细节

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

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

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

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

x + 5是一个Intincrease xs是一个[Int]

让我们看看你的功能。它的类型是contains :: String -> String -> Bool这样的,它需要一个字符串,然后是一个字符串,然后给你一个布尔值。之后=你就得到了prefix xs (y:ys)。现在prefix有相同的类型:prefix :: String -> String -> Bool,所以现在我们给了它xs(y:ys)它给了我们一个布尔值。

在行的末尾,我们也得到了contains xs ys一个布尔值,所以如果我们把它们放在:它们之间,我们就会得到一些类似的东西

False : True

但我们不允许这样做,因为True它不是一个列表。(记住(:) :: a -> [a] -> [a]。)你可以做False:[True](​​这将是[False,True],但这不是你想要的。

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

xs如果它在(y:ys)它的前面 ( prefix xs (y:ys)) 或者它在ys( contains xs ys) 中的某个地方,它就在里面。

里面有:(put-in-front-of 符号) 它会说

xs如果它在(y:ys)它的前面(prefix xs (y:ys)),则将那个答案放在这些答案的前面 - 它在yscontains xs ys)中的某个地方。

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

于 2012-10-25T23:18:20.937 回答