Yuki2222
Yuki2222

Reputation: 33

Haskell Replicate according to number value

I have the following problem, I want to replicate numbers according to their value in a list, but if it's lower than 0, they do not appear. For example:

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

I was thinking of using my version of replicate (which I'm also using for something else so I can't change the Int -> a -> [a]) but I don't know why there is a complication error, please help me fix, but without the use of map.

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

Upvotes: 1

Views: 218

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477210

You append with myReplicate xs, but xs is a list of Ints. You should recurse on the tail of the list, so:

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

This then produces:

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

It might be better however to make myReplicate work with any Int, so:

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

then your myList can be simplified to:

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

We can also make use of concatMap :: (a -> [b]) -> [a] -> [b]:

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

we can generalize this further to let this work with any Foldable:

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

Upvotes: 1

Related Questions