Junhan Liu
Junhan Liu

Reputation: 55

Haskell how could I repeat elements in list when I reach the last one element in the list?

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

Answers (2)

chi
chi

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

Netwave
Netwave

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

Related Questions