2015-11-18 04:15:10 +03:00
|
|
|
module Interpreter (interpret) where
|
2015-11-18 04:05:16 +03:00
|
|
|
|
|
|
|
import Algorithm
|
|
|
|
import Control.Monad.Free
|
|
|
|
import Control.Comonad.Cofree
|
|
|
|
import Operation
|
|
|
|
import Diff
|
2015-11-18 04:29:18 +03:00
|
|
|
import Syntax
|
2015-11-18 04:50:15 +03:00
|
|
|
import Data.Map
|
2015-11-18 05:23:53 +03:00
|
|
|
import Patch
|
2015-11-18 18:11:05 +03:00
|
|
|
import SES
|
2015-11-18 04:05:16 +03:00
|
|
|
|
2015-11-18 21:59:40 +03:00
|
|
|
constructAndRun :: Eq a => Term a Info -> Term a Info -> Maybe (Diff a)
|
2015-11-18 04:17:45 +03:00
|
|
|
constructAndRun a b =
|
2015-11-18 21:52:09 +03:00
|
|
|
run $ algorithm a b where
|
|
|
|
algorithm (_ :< Indexed a) (_ :< Indexed b) = Free $ ByIndex a b (Pure . Free . Indexed)
|
2015-11-18 21:52:49 +03:00
|
|
|
algorithm (_ :< Keyed a) (_ :< Keyed b) = Free $ ByKey a b (Pure . Free . Keyed)
|
2015-11-18 21:59:40 +03:00
|
|
|
algorithm (_ :< Leaf a) (_ :< Leaf b) | a == b = Pure . Free $ Leaf b
|
2015-11-18 21:53:59 +03:00
|
|
|
algorithm a b = Free $ Recursive a b Pure
|
2015-11-18 04:05:16 +03:00
|
|
|
|
2015-11-18 21:59:40 +03:00
|
|
|
run :: Eq a => Algorithm a (Diff a) -> Maybe (Diff a)
|
2015-11-18 04:05:16 +03:00
|
|
|
run (Pure diff) = Just diff
|
2015-11-18 05:26:07 +03:00
|
|
|
|
2015-11-18 04:59:01 +03:00
|
|
|
run (Free (Recursive a b f)) = run . f $ recur a b where
|
2015-11-18 04:29:18 +03:00
|
|
|
recur (_ :< Indexed a') (_ :< Indexed b') | length a' == length b' =
|
2015-11-18 04:59:01 +03:00
|
|
|
Free . Indexed $ zipWith interpret a' b'
|
2015-11-18 04:35:00 +03:00
|
|
|
recur (_ :< Fixed a') (_ :< Fixed b') | length a' == length b' =
|
2015-11-18 04:59:01 +03:00
|
|
|
Free . Fixed $ zipWith interpret a' b'
|
2015-11-18 04:50:15 +03:00
|
|
|
recur (_ :< Keyed a') (_ :< Keyed b') | keys a' == keys b' =
|
2015-11-18 05:16:39 +03:00
|
|
|
Free . Keyed . fromList . fmap repack $ keys b' where
|
|
|
|
repack key = (key, interpretInBoth key a' b')
|
2015-11-18 04:50:15 +03:00
|
|
|
interpretInBoth key a' b' = maybeInterpret (Data.Map.lookup key a') (Data.Map.lookup key b')
|
|
|
|
maybeInterpret (Just a) (Just b) = interpret a b
|
2015-11-18 05:44:55 +03:00
|
|
|
recur _ _ = Pure $ Replace a b
|
2015-11-18 04:13:48 +03:00
|
|
|
|
2015-11-18 11:21:27 +03:00
|
|
|
run (Free (ByKey a b f)) = run $ f byKey where
|
|
|
|
byKey = unions [ deleted, inserted, patched ]
|
|
|
|
deleted = (Pure . Delete) <$> difference a b
|
|
|
|
inserted = (Pure . Insert) <$> difference b a
|
|
|
|
patched = intersectionWith interpret a b
|
|
|
|
|
2015-11-18 21:44:02 +03:00
|
|
|
run (Free (ByIndex a b f)) = run . f $ ses constructAndRun cost a b
|
2015-11-18 18:02:47 +03:00
|
|
|
|
2015-11-18 21:59:40 +03:00
|
|
|
interpret :: Eq a => Term a Info -> Term a Info -> Diff a
|
2015-11-18 04:17:45 +03:00
|
|
|
interpret a b = maybeReplace $ constructAndRun a b where
|
2015-11-18 04:13:48 +03:00
|
|
|
maybeReplace (Just a) = a
|
2015-11-18 05:44:55 +03:00
|
|
|
maybeReplace Nothing = Pure $ Replace a b
|