mirror of
https://github.com/github/semantic.git
synced 2024-12-26 08:25:19 +03:00
Merge branch 'ordered-map-but-this-time-working' into split-rendering-of-keyed-nodes
This commit is contained in:
commit
aa8a36e36c
@ -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
|
||||
|
||||
|
@ -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) ]
|
||||
|
Loading…
Reference in New Issue
Block a user