声明类型并定义一个函数,该函数接受一个数字列表并返回一个列表,该列表中所有正元素均递增(增1),而负数递减(减1)。同样,如果列表中有0,它将被消除。
例如fun [2,-4,0,66,-1]会返回[3,-5,67,-2]
我在两个filter和map语句与zipWith(++)之间尝试(++)
这是我的代码,它会给出编译错误。
incDec (x:xs) = map (+1) $ filter (>0) (x:xs) (++)
map (-1) $ filter (<0) (x:xs)
答案 0 :(得分:4)
$
将比其他任何运算符都更松散地绑定,因此您需要显式括号。另外,您不需要解构列表,因为您只是将其放回原处(x:xs
模式是不必要的,并且会破坏空白列表中的功能)
incDec xs = (map (+1) $ filter (>0) xs) ++
(map (subtract 1) $ filter (<0) xs)
(请参阅here,以了解为什么我使用上面的subtract
而不是-
)
但是,这仍然不能满足您的要求。由于您要进行两次过滤和映射,因此最终所有正数都将在开头,而负数将在结尾,因此您将失去列表的原始顺序。相反,我们将使用concatMap
,它可以用作一种混合过滤器/地图。
incDec :: (Ord a, Num a) => [a] -> [a]
incDec = concatMap go -- Do the map / filter combination
where go x = case x `compare` 0 of -- Compare the number to 0
LT -> [x - 1] -- If negative, subtract one
GT -> [x + 1] -- If positive, add one
EQ -> [] -- If zero, eliminate
用法示例:
*Main> incDec [2, -4, 0, 66, -1]
[3,-5,67,-2]