Haskell 根据数值复制

Haskell Replicate according to number value

我有以下问题,我想根据列表中的值复制数字,但如果它小于 0,它们就不会出现。例如:

myList [1, 4, 3] = [1, 4, 4, 4, 4, 3, 3, 3]
myList  [1, 0, 2] = [1, 2, 2]

我正在考虑使用我的复制版本(我也将其用于其他用途,所以我无法更改 Int -> a -> [a])但我不知道为什么会出现复杂错误,请帮我修复,但没有使用地图。

myList:: [Int] -> [Int]
myList [] = []
myList (x:xs) = (myReplicate (if x > 0 then x else 0) x) ++ myReplicate xs

myReplicate :: Int -> a -> [a]
myReplicate 0 x = [ ]
myReplicate count x = x : myReplicate (count-1) x

您追加 myReplicate xs,但 xsInt 的列表。你应该在列表的尾部递归,所以:

myList:: [Int] -> [Int]
myList [] = []
myList (x:xs) = (myReplicate (if x > 0 then x else 0) x) ++ <b>myList xs</b>

然后生成:

Prelude> myList [1,4,3]
[1,4,4,4,4,3,3,3]

然而,让 myReplicate 与任何 Int 一起工作可能会更好,所以:

myReplicate :: Int -> a -> [a]
myReplicate n _ | <b>n <= 0</b> = []
myReplicate count x = x : myReplicate (count-1) x

那么你的myList可以简化为:

myList:: [Int] -> [Int]
myList [] = []
myList (x:xs) = myReplicate x x ++ myList xs

我们也可以利用concatMap :: (a -> [b]) -> [a] -> [b]:

myList:: [Int] -> [Int]
myList = concatMap (\x -> myReplicate x x)

我们可以进一步概括这一点,让它适用于任何 Foldable:

myList:: <b>Foldable f</b> => <b>f</b> Int -> [Int]
myList = concatMap (\x -> myReplicate x x)