Skip to content

Instantly share code, notes, and snippets.

@rsslldnphy
Last active August 29, 2015 14:02
Show Gist options
  • Save rsslldnphy/b32f30398fab37bcb5cc to your computer and use it in GitHub Desktop.
Save rsslldnphy/b32f30398fab37bcb5cc to your computer and use it in GitHub Desktop.
{- | given two positions in a list, swap them.
if (at least) one of the positions is invalid, return Nothing.
Examples:
>>> swapL 0 2 [0..5]
Just [2,1,0,3,4,5]
>>> fmap (take 6) $ swapL 0 2 [0..]
Just [2,1,0,3,4,5]
prop> \(x,y) -> swapL x y [] == Nothing
prop> \(n,xs) -> swapL n n xs == Just xs
-}
swapL :: Int -> Int -> [a] -> Maybe [a]
swapL a b xs
| min a b < 0 = Nothing
| not $ atLeast (max a b) xs = Nothing
| otherwise = Just $ zipWith swap xs [0..]
where swap x i
| i == a = xs !! b
| i == b = xs !! a
| otherwise = x
atLeast 0 _ = True
atLeast _ [] = False
atLeast n xs' = atLeast (n - 1) (tail xs')
main :: IO ()
main = do
print (swapL 0 2 [0..5] :: Maybe [Int])
print $ fmap (take 6) (swapL 0 2 [0..] :: Maybe [Int])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment