如果我们看看你的定义,
exists :: (t -> Bool) -> [t] -> Bool
exists f a []=error
exists f a (x:xs)
|if x∈f a =True
|otherwise= x:f a xs
我们看到你的类型是
exists :: (t -> Bool) -> [t] -> Bool
所以exists
必须带两个参数,一个类型为(t -> Bool)
的谓词函数和一个类型为[t]
的列表。它返回一个Bool
。根据我们的规范意图,这看起来没问题。
让我们看看你的条件的第一行:
exists f a [] = error
此功能突然有三个参数。 f
和空列表构造函数[]
看起来没问题,但在类型说明中未提及a
。因此,我们删除它:
exists f [] = error
现在,返回的error
不是布尔值。但规范说它一定是。让我们假设我们要求exists (<2) []
。那么问题的自然答案是True
或False
?或换言之,是否有任何元素x in []
满足谓词f x
?
到下一行,
exists f a (x:xs)
|if x∈f a =True
|otherwise= x:f a xs
我们了解到,a
具有由类型规范中去,所以让我们修剪它。由于我们现在对a
自然不喜欢,所以为什么不在发生的任何地方修剪它。此外,由于if
会产生一个语法错误,让我们摆脱这种过于自我:
exists f (x:xs)
| x∈f = True
| otherwise = x:f xs
的x∈f
没有多大意义,但f x
一样。如果f x
返回true,则将采取后卫变体。现在,这里返回的True听起来是正确的。它表示我们已经在列表中找到与谓词相匹配的元素 - 并且看到了,可能是x
!
所以我们把注意力转向最后一行。 otherwise
表示后卫f x
未返回True。因此,x
不满足谓词,所以我们必须搜索列表的其余部分。
右边x : f xs
是特有的。 :
表示我们将尝试返回一个列表,但函数的返回类型是Bool
。如果我们尝试这种方式,类型检查器不会喜欢我们。此外,我们没有理由再看x
,因为我们只是确定它不符合谓词。
你缺少的关键是我们需要递归在这一点上。我们需要以某种方式搜索列表的尾部xs
- 递归意味着调用尾部的exists
函数。
您的一般轨道是正确的,但再次询问是否有不清楚的地方。一种诀窍可能是按照递归情况的类型:“我需要提供exists
才能返回Bool
值?”。
请注意`(x :: xs)`是一个错字。它应该是`(x:xs)`。 – 2011-01-24 00:28:44