1
1
mirror of https://github.com/github/semantic.git synced 2024-12-25 16:02:43 +03:00

Merge branch 'ordered-map-but-this-time-working' into split-rendering-of-keyed-nodes

This commit is contained in:
Rob Rix 2015-12-14 18:27:50 -05:00
commit aa8a36e36c
2 changed files with 35 additions and 12 deletions

View File

@ -10,7 +10,8 @@ import Syntax
import Term
import Control.Monad.Free
import Control.Comonad.Cofree hiding (unwrap)
import OrderedMap
import qualified OrderedMap as Map
import OrderedMap ((!))
import Data.Maybe
hylo :: Functor f => (t -> f b -> b) -> (a -> (t, f a)) -> a -> b
@ -40,21 +41,20 @@ run _ (Pure diff) = Just diff
run comparable (Free (Recursive (annotation1 :< a) (annotation2 :< b) f)) = run comparable . f $ recur a b where
recur (Indexed a') (Indexed b') | length a' == length b' = annotate . Indexed $ zipWith (interpret comparable) a' b'
recur (Fixed a') (Fixed b') | length a' == length b' = annotate . Fixed $ zipWith (interpret comparable) a' b'
recur (Keyed a') (Keyed b') | keys a' == keys b' = annotate . Keyed . fromList . fmap repack $ keys b'
recur (Keyed a') (Keyed b') | Map.keys a' == bKeys = annotate . Keyed . Map.fromList . fmap repack $ bKeys
where
bKeys = Map.keys b'
repack key = (key, interpretInBoth key a' b')
interpretInBoth key x y = maybeInterpret (lookup key x) (lookup key y)
maybeInterpret (Just x) (Just y) = interpret comparable x y
maybeInterpret _ _ = error "maybeInterpret assumes that its operands are `Just`s."
interpretInBoth key x y = interpret comparable (x ! key) (y ! key)
recur _ _ = Pure $ Replace (annotation1 :< a) (annotation2 :< b)
annotate = Free . Annotated (annotation1, annotation2)
run comparable (Free (ByKey a b f)) = run comparable $ f byKey where
byKey = unions [ deleted, inserted, patched ]
deleted = (Pure . Delete) <$> difference a b
inserted = (Pure . Insert) <$> difference b a
patched = intersectionWith (interpret comparable) a b
byKey = Map.unions [ deleted, inserted, patched ]
deleted = (Pure . Delete) <$> Map.difference a b
inserted = (Pure . Insert) <$> Map.difference b a
patched = Map.intersectionWith (interpret comparable) a b
run comparable (Free (ByIndex a b f)) = run comparable . f $ ses (constructAndRun comparable) diffCost a b

View File

@ -9,13 +9,36 @@ spec = do
it "should return those elements of a not in b" $
Map.difference a b `shouldBe` (Map.fromList [ ("a", 1) ])
it "is asymmetrical" $ do
Map.difference a b `shouldNotBe` Map.difference b a
describe "union" $ do
it "should return those elements in either a or b" $
Map.union a b `shouldBe` (Map.fromList $ ("a", 1) : Map.toList b)
Map.union a b `shouldBe` (Map.fromList $ Map.toList a ++ [ ("d", -4) ])
it "is asymmetrical" $ do
Map.union a b `shouldNotBe` Map.union b a
describe "unions" $ do
it "is equivalent to `union` for two maps" $
Map.unions [ a, b ] `shouldBe` Map.union a b
it "does not duplicate elements" $
Map.unions [ a, b, a, b, a, b ] `shouldBe` Map.union a b
describe "intersectionWith" $ do
it "should return those elements in both a and b, combined with a function" $
Map.intersectionWith (+) a b `shouldBe` (Map.fromList [ ("b", 4), ("c", 6) ])
Map.intersectionWith (-) a b `shouldBe` (Map.fromList [ ("b", 4), ("c", 6) ])
it "is asymmetrical" $ do
Map.intersectionWith (-) a b `shouldNotBe` Map.intersectionWith (-) b a
describe "keys" $ do
it "should return all the keys in a map" $
Map.keys a `shouldBe` [ "a", "b", "c" ]
it "is ordered" $
Map.keys (Map.union b a) `shouldBe` [ "b", "c", "d", "a" ]
where a = Map.fromList [ ("a", 1), ("b", 2), ("c", 3) ]
b = Map.fromList [ ("b", 2), ("c", 3), ("d", 4) ]
b = Map.fromList [ ("b", -2), ("c", -3), ("d", -4) ]