Skip to content

Instantly share code, notes, and snippets.

@jml

jml/compare.hs Secret

Created August 15, 2016 19:33
Show Gist options
  • Save jml/c308c351d2ccf39d03a421370d7e48df to your computer and use it in GitHub Desktop.
Save jml/c308c351d2ccf39d03a421370d7e48df to your computer and use it in GitHub Desktop.
#!/usr/bin/env stack
-- stack --resolver lts-6 --install-ghc runghc --package protolude
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
import Protolude
getDifferences :: (Ord a, Ord b, Eq c) => (a -> (b, c)) -> [a] -> [a] -> [(b, (c, c))]
getDifferences _ _ [] = []
getDifferences _ [] _ = []
getDifferences splitter xs@(x:xs') ys@(y:ys') =
let (x1, x2) = splitter x
(y1, y2) = splitter y
in
case compare x1 y1 of
LT -> getDifferences splitter xs' ys
GT -> getDifferences splitter xs ys'
EQ ->
let next = getDifferences splitter xs' ys' in
if x2 == y2
then next
else (x1, (x2, y2)):next
main :: IO ()
main = do
let left = [("foo", 1),("bar", 2),("baz", 3)] :: [(Text, Int)]
let right = [("foo", 1),("bar", 3),("baz", 3)]
putStrLn $ (show $ getDifferences identity left right :: Text)
@PiDelport
Copy link

If I understand the logic of this right, this should be the same thing using Map?

import qualified Data.Map.Strict as M


getDifferences :: (Ord k, Eq v) => M.Map k v -> M.Map k v -> M.Map k (v, v)
getDifferences = M.mergeWithKey compare ignore ignore
  where
    compare k x y = if x == y then Nothing else Just (x, y)
    ignore = const M.empty


main :: IO ()
main = do
  let left = M.fromList [("foo", 1),("bar", 2),("baz", 3)] :: M.Map Text Int
  let right = M.fromList [("foo", 1),("bar", 3),("baz", 3)] :: M.Map Text Int
  putStrLn $ (show $ getDifferences left right :: Text)

@jml
Copy link
Author

jml commented Aug 15, 2016

Yes, that's right. Thanks.

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