Skip to content

Instantly share code, notes, and snippets.

@ijt
Created March 10, 2012 04:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ijt/2010183 to your computer and use it in GitHub Desktop.
Save ijt/2010183 to your computer and use it in GitHub Desktop.
Swap two elements of a list in Haskell, with a QuickCheck test
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
@southp
Copy link

southp commented Mar 4, 2013

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 : )

@csivanich
Copy link

Mark me as another thankful Googler, was having trouble with swapping elements until I read your implementation. Simple and easy to understand. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment