John C.
John C.

Reputation: 445

Rotating a list in Haskell with all posibilities

How can I edit the following code to make Haskell show all the possibilities of rotating an input list from the user :

rotate ::  Int -> [a] -> [a]
rotate n text = take (length text) (drop n (cycle text)) 

I assume that to print all the possibilities we need to drop the first element X times. where X is the length of the list entered.

circle ::  [a] -> [[a]]
circle text = take (length text) (drop (1) (cycle text))

I can't perform the operation where the list is printed X times. Also I have errors while running the above code which states the following: Couldn't match type ‘a’ with ‘[a]’

I wanted the Output to be something like that:

circle "ab"
["ab","ba"]

Upvotes: 2

Views: 303

Answers (3)

amalloy
amalloy

Reputation: 92117

You can avoid any calls to length, as well as the repeated calls to cycle and ever-larger arguments to drop, by instead zipping any otherwise-infinite lists against the finite input list, to trim them to be the size you expect, discarding later elements:

circle xs = let trim ys = zipWith const ys xs
            in trim . map trim . iterate tail . cycle $ xs

*Main> circle "abc"
["abc","bca","cab"]

Upvotes: 7

Code-Apprentice
Code-Apprentice

Reputation: 83567

I would start by reusing the rotate function and apply some recursion:

circle text = text : (circle $ rotate text)

Now this produces an infinite list. If you only want each rotation once, then use take:

circle text = take (length text) $ text : (circle $ rotate text)

This version has the disadvantage of calculating the length of text each time you call circle. Instead, you could use a helper function with a counter that decrements for each recursion:

circle = circle' (length text)
  where circle' 0 _ = []
        circle' n text = text : (circle' (rotate text) (n - 1))

Upvotes: 0

Zazaeil
Zazaeil

Reputation: 4104

Seems like you're interested in all permutations of all permutations. It means that you're dealing with a [ [] ] - list of list (recall that "ab" is just ['a', 'b']). Data.List has what you need. Source code. Otherwise, I've completely misunderstood your intention.

Upvotes: 0

Related Questions