我有一个问题,为什么这个函数不能与“:”一起使用,但可以与 || 一起使用 以及为什么将“:”替换为|| 我的意思是为什么不能写
包含 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
关键思想
用于:建立一个列表答案,||或&&建立一个真/假答案,和/+或*建立一个数字答案。想想你正在结合什么——它不必一直:都是。
细节
我想你的意思是问为什么你不能写
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是一个Int和increase 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)),则将那个答案放在这些答案的前面 - 它在ys(contains xs ys)中的某个地方。
这是没有意义的。这就是为什么您需要或 ( ||) 不在 ( ) 前面的原因:。