Reputation: 445
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
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
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
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