Reputation: 55
I an new to Haskell programming, and I was tending to create a function that can repeat each elements in the list in n times, the problem is when I reach the last one element from the list and I want to return to the first one in the element and do it again, Like
repeat :: Int -> [t] ->[t]
repeat 0 [] = []
repeat n (x:xs)
| n > 0 = x : repeat (n-1) xs
| n < 0 =[]
This only can print the list when n is exactly the same as the size of the list, and there would be error if n > length list The possible result should be like this:
repeat 6 [1,2,3]
the desired result would be : 1,2,3,1,2,3
what should I edit if I want to get the first element in the list and print again? Thanks!
Upvotes: 0
Views: 975
Reputation: 116139
A basic alternative is to keep two lists around: one of them is "consumed" through pattern matching, while the other remembers the full list, so that we can start over when needed.
-- requires n >= 0 and nonempty full
repeatAux :: Int -> [t] -> [t] ->[t]
repeatAux 0 _ _full = []
repeatAux n [] full = repeatAux n full full
repeatAux n (x:xs) full = x : repeatAux (n-1) xs full
repeat :: Int -> [t] ->[t]
repeat n _ | n <= 0 = []
repeat _ [] = error "repeat: empty list with n>0"
repeat n full = repeatAux n full full
This can be improved using a local function, so that we can avoid to pass around the full
list.
repeat :: Int -> [t] ->[t]
repeat n _ | n <= 0 = []
repeat _ [] = error "repeat: empty list with n>0"
repeat n full = go n full
where
go 0 _ = []
go n [] = go n full
go n (x:xs) = x : go (n-1) xs
Upvotes: 1
Reputation: 42678
As Mark Seemann comment is as simple as taking n
elements from the cycle of the list, so
repeat :: Int -> [t] -> [t]
repeat n = take n . cycle
If you want a fully expanded code would be more or less like this:
repeat :: Int -> [t] ->[t]
repeat 0 [] = []
repeat n (x:xs) | n > 0 = x : repeat (n-1) (xs ++ [x])
| otherwise = []
The idea is that each item you consume you append to the list to be processed. Here you have a live example
Upvotes: 4