Created
March 10, 2012 04:52
-
-
Save ijt/2010183 to your computer and use it in GitHub Desktop.
Swap two elements of a list in Haskell, with a QuickCheck test
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module SwapElts where | |
-- If you have to use this function, arrays may be a better choice. | |
swapElts i j ls = [get k x | (k, x) <- zip [0..length ls - 1] ls] | |
where get k x | k == i = ls !! j | |
| k == j = ls !! i | |
| otherwise = x | |
-- This is a nice example of how to efficiently generate test cases. | |
-- A naive approach would have been to take separate arguments for | |
-- the list and two indices in the QuickCheck property below. | |
-- Most of the generated test cases would be rejected that way. | |
data SwapEltsExample = SwapEltsExample Int Int [Int] deriving (Show) | |
instance Arbitrary SwapEltsExample where | |
arbitrary = do | |
ls <- listOf1 arbitrary | |
let n = length ls | |
i <- choose (0, n-1) | |
j <- choose (0, n-1) | |
return $ SwapEltsExample i j ls | |
-- en.wikipedia.org/wiki/Involution | |
prop_swapElts_isAnInvolution :: SwapEltsExample -> Bool | |
prop_swapElts_isAnInvolution example = (se . se) ls == ls | |
where se = swapElts i j | |
SwapEltsExample i j ls = example |
Mark me as another thankful Googler, was having trouble with swapping elements until I read your implementation. Simple and easy to understand. Thanks!
not so beautiful but faster (don't know why):
swapItems :: (Int, Int) -> [a] -> [a]
swapItems (i, j) l
| i == j = l
| i > j = swapItems (j, i) l
| otherwise = take i l ++ [item2] ++ take (j - i - 1) (drop (i + 1) l) ++ [item1] ++ drop (j + 1) l
where
item1 = l !! i
item2 = l !! j
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi. I was recently starting to learn haskell and confused about how to write a elegant swapElts until I googled your gist. Both useful and informative. Thanks a lot : )