我不清楚你想要接下来的三个功能中的哪一个,所以我已经完成了它们:
testListAll :: [a -> Bool] -> a -> Bool
testListAll xs a = and $ map ($ a) xs
testListAny :: [a -> Bool] -> a -> Bool
testListAny xs a = or $ map ($ a) xs
testListList :: [a -> Bool] -> a -> [Bool]
testListList xs a = map ($ a) xs
例如,
> testListAll [(> 5), (== 7), even] 4
False
> testListAny [(> 5), (== 7), even] 4
True
> testListAll [(> 5), (== 8), even] 8
True
> testListList [(> 5), (== 8), even] 10
[True,False,True]
现在我们可以编写如下函数
test :: Integral a => a -> Bool
test n = if even n
then testListAll [(> 5), (< 9)] n
else testListAny [(<= 5), (> 8)] n
给予
> test 5
True
> test 6
True
> test 7
False
> test 8
True
> test 9
True
> test 10
False
> test 11
True
解释
我将详细解释一个功能;其他人的工作方式非常相似。
第一个函数可能更简单地写成:
testListAll' :: [a -> Bool] -> a -> Bool
testListAll' xs a = and [f a | f <- xs]
所以它所做的就是f
从列表中获取每个测试函数并将其应用于测试值a
。如果列表中的所有内容都为 True,则该函数and :: [Bool] -> Bool
给出 True;此函数检查是否满足所有检查。
那么为什么我把右手边写成and $ map ($ a) xs
?好吧,[f a | f <- xs]
因为我对 的所有元素都做同样的事情f
,xs
所以我立即想到用map
.
先想想
map (+ 4) [1,2,3,4]
= [(+4) 1, (+4) 2, (+4) 3, (+4) 4]
= [1+4, 2+4, 3+4, 4+4]
= [5,6,7,8]
看看我们如何使用(低优先级)函数应用运算符$
map ($ a) [(>4), (==7), (<10)]
= [($ a) (>4), ($ a) (==7), ($ a) (<10)]
= [(>4) $ a, (==7) $ a, (<10) $ a]
= [(>4) a, (==7) a, (<10) a]
= [a > 4 , a==7, a < 10]
这给你的结果与[f a| a <- [(>4), (==7), (<10)]]
.