Skip to content

Instantly share code, notes, and snippets.

@ijt
Created March 10, 2012 04:52
Show Gist options
  • 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!

@Shaeto
Copy link

Shaeto commented May 22, 2024

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