Kevin,<br><br>Below is my attempt, which hopefully is bad enough to get this thread rolling for you. :) <br><br>It rotates the 'i'th element 'n' times by swapping the 'i'th element with the element to its right 'n' times. It looks horribly inefficient to me, but is fairly simple and only depends on the prelude. I think it ought to be possible to reduce this to a very simple function with no recursion and one strategic splitAt, but I've run out of time to work more on it. :(
<br><br><span style="font-family: courier new,monospace;">rotate :: [a] -> Int -> Int -> [a]</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">rotate xs i n = snd (iterate swap (i,xs) !! n)
</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">swap :: (Int, [a]) -> (Int, [a])</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">swap (i,xs) </span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> | i == length xs - 1 = (0, last xs : init (tail xs) ++ [head xs])
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> | otherwise = (i + 1, start ++ [right,left] ++ end)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> where</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (start, left:right:end) = splitAt i xs</span><br><br>
-Greg<br><br><br><br><br><div><span class="gmail_quote">On 6/4/07, <b class="gmail_sendername">kevin birch</b> <<a href="mailto:kbirch@pobox.com" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">
kbirch@pobox.com</a>> wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div><div><span><div>On 火, 2007-6月-05, at 02:54, Greg Fitzgerald wrote:</div><br><blockquote type="cite"><font size="3"><span style="font-size: 11px;">> rotating the fourth element 2 positions would result in: [1, 2, 4, 3, 5]
</span></font><br>Seems odd. Should that be [4,1,2,3,5]?<br><br></blockquote></span>Yes, I meant to use the 5 element in my second example. Sorry for the confusion.</div><div><span><br><blockquote type="cite">
<font size="3"><span style="font-size: 11px;"> > Is there an idomatic way to handle both of these cases in a function?</span></font><br>Generally people like to see your attempt at a solution before giving the idomatic one so that they are sure it's not a homework question. What do you have so far?
<br><br></blockquote></span>Yeah, I only wish I had gone to a school that would be forward thinking enough to each FP. ;-)</div><div><br></div><div>Here is my version:</div><div><br></div><div>rotate :: Array Integer Card -> Integer -> Integer -> Array Integer Card
</div><div>rotate a i n</div><div> | i <= u - n = a // [(i, a ! (i + 1)), (i + 1, a ! (i + 2)), (i + 2, a ! i)]</div><div> | otherwise = a // zip [l..u] (h ++ [a ! i] ++ filter (not . (== (a ! i))) t)</div><div>
where (l, u) = bounds a
</div><div> (h, t) = splitAt (fromInteger ((i - u) + n)) $ elems a</div><div><br></div><div>This function is part of my implementation of the Solitaire encryption algorithm, so that is why I have the reference to a Card data type. This does what I want, and seems basically idiomatic, but perhaps it could be better.
</div><div><br></div><div>Thanks,</div><span><div>Kevin</div><br></span></div></blockquote></div><br>