正数递增和负数递减1

时间:2019-06-06 01:49:39

标签: haskell

声明类型并定义一个函数,该函数接受一个数字列表并返回一个列表,该列表中所有正元素均递增(增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)

1 个答案:

答案 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]