我需要一个程序来检查所有元素对之间的差异是否在-2到( >= -2 && < 2)
的区间内。如果是,则返回True
,否则返回False
。例如,[1,2,3]
为True
,但[1,3,4]
为False
。
我正在使用all
函数。我的if
条款有什么问题?
allfunc (x : xs)
= if all (...) xs
then allfunc xs
else [x] ++ allfunc xs
allfunc _
= []
或者我做错了什么?
答案 0 :(得分:3)
为此,使用列表推导或编号可能更容易。
pairsOf lst = do
x <- lst
y <- lst
return (x, y)
pairsOf
返回输入lst
中的数字对列表。例如,pairsOf [1,2,3]
会产生[(1,1),(1,2),(1,3),(2,1),(2,2),(2,3),(3,1),(3,2),(3,3)]
。
现在,您可以在单行\(x, y) -> x - y
中定义一对之间的差异,并将其映射到列表中:
differences lst = map (\(x, y) -> x - y) (pairsOf lst)
现在您只需确保differences lst
中的每个元素都在-2
和2
之间。
当然,这只是一种可行的方法。还有很多其他方法。
答案 1 :(得分:2)
你所描述的天真的方式是:
allfunc xs = all (<=2) [abs(a-b) | a <- xs, b <- xs ]
但是,更有效的方法是比较列表的最小值和最大值:
fastfunc [] = true
fastfunc xs = maximum xs - minimum xs <= 2
答案 2 :(得分:1)
为什么不简单......
allfunc xs = (maximum xs - minimum xs) <= 2
或者,如果你真的想调查每一对,你可以使用monads:
import Control.Monad
allfunc xs = all ((<=2).abs) $ liftM2 (-) xs xs
来自liftA2
的 Control.Applicative
也可以。
答案 3 :(得分:0)
嗯,问题规范不是很清楚。
你说:
所有元素之间的差异在-2到2之间的间隔(&gt; = -2&amp;&amp;&lt; 2)
但是:
敌人示例,[1,2,3]为True,但[1,3,4]为假
[1,2,3]的真实情况如何?
假设你的意思是-2 <= diff <= 2
,那么我会用这个:
allfunc :: (Ord a, Num a) => [a] -> Bool
allfunc theList = all (\x -> (x >= -2) && (x<2)) [x-y | x <- theList, y <- theList ]
allfunc [1,2,3] -- => True
allfunc [1,3,4] -- => False
答案 4 :(得分:-1)
基本上,是的,你做错了什么。 all
旨在获取谓词和值列表以进行测试。因此,当且仅当应用于给定谓词函数时所有值都为true时,它将返回True
。即:
allValuesEven = all even
allValuesOdd = all odd