2016-06-03 23:02:06 +03:00
|
|
|
|
{-# LANGUAGE TypeFamilies, TypeSynonymInstances #-}
|
2015-11-18 00:25:36 +03:00
|
|
|
|
module Diff where
|
|
|
|
|
|
2016-05-26 19:58:04 +03:00
|
|
|
|
import Prologue
|
2016-05-03 22:50:38 +03:00
|
|
|
|
import Data.Functor.Foldable as Foldable
|
2016-06-27 19:02:25 +03:00
|
|
|
|
import Data.Functor.Both as Both
|
|
|
|
|
import qualified Data.OrderedMap as Map
|
2015-11-18 05:23:53 +03:00
|
|
|
|
import Patch
|
2016-02-29 18:04:59 +03:00
|
|
|
|
import Syntax
|
|
|
|
|
import Term
|
2015-11-18 00:25:36 +03:00
|
|
|
|
|
2016-01-14 20:30:21 +03:00
|
|
|
|
-- | An annotated series of patches of terms.
|
2016-06-01 03:16:19 +03:00
|
|
|
|
type DiffF leaf annotation = FreeF (CofreeF (Syntax leaf) (Both annotation)) (Patch (Term leaf annotation))
|
2016-05-03 21:10:25 +03:00
|
|
|
|
type Diff a annotation = Free (CofreeF (Syntax a) (Both annotation)) (Patch (Term a annotation))
|
2016-05-03 22:50:38 +03:00
|
|
|
|
|
2016-05-04 21:37:24 +03:00
|
|
|
|
type instance Base (Free f a) = FreeF f a
|
2016-05-03 22:50:38 +03:00
|
|
|
|
instance (Functor f) => Foldable.Foldable (Free f a) where project = runFree
|
2016-05-13 18:44:03 +03:00
|
|
|
|
instance (Functor f) => Foldable.Unfoldable (Free f a) where embed = free
|
2015-11-18 00:25:36 +03:00
|
|
|
|
|
2015-12-01 03:06:48 +03:00
|
|
|
|
diffSum :: (Patch (Term a annotation) -> Integer) -> Diff a annotation -> Integer
|
2015-12-01 18:13:05 +03:00
|
|
|
|
diffSum patchCost diff = sum $ fmap patchCost diff
|
2015-12-01 03:06:48 +03:00
|
|
|
|
|
2016-04-11 22:06:59 +03:00
|
|
|
|
-- | The sum of the node count of the diff’s patches.
|
2015-11-27 20:06:14 +03:00
|
|
|
|
diffCost :: Diff a annotation -> Integer
|
2015-12-01 03:16:22 +03:00
|
|
|
|
diffCost = diffSum $ patchSum termSize
|
2016-06-27 19:02:25 +03:00
|
|
|
|
|
2016-06-27 19:37:27 +03:00
|
|
|
|
merge :: (Patch (Term leaf annotation) -> Term leaf annotation) -> Diff leaf annotation -> Term leaf annotation
|
|
|
|
|
merge transform = cata algebra . fmap transform
|
|
|
|
|
where algebra :: FreeF (CofreeF (Syntax leaf) (Both annotation)) (Term leaf annotation) (Term leaf annotation) -> Term leaf annotation
|
|
|
|
|
algebra (Pure p) = p
|
|
|
|
|
algebra (Free (annotations :< syntax)) = cofree (Both.fst annotations :< syntax)
|
|
|
|
|
|
2016-06-27 19:49:44 +03:00
|
|
|
|
mergeMaybe :: (Patch (Term leaf annotation) -> Maybe (Term leaf annotation)) -> Diff leaf annotation -> Maybe (Term leaf annotation)
|
|
|
|
|
mergeMaybe transform = cata algebra . fmap transform
|
|
|
|
|
where algebra :: FreeF (CofreeF (Syntax leaf) (Both annotation)) (Maybe (Term leaf annotation)) (Maybe (Term leaf annotation)) -> Maybe (Term leaf annotation)
|
|
|
|
|
algebra (Pure p) = p
|
|
|
|
|
algebra (Free (annotations :< syntax)) = Just . cofree $ Both.fst annotations :< case syntax of
|
|
|
|
|
Leaf s -> Leaf s
|
|
|
|
|
Indexed i -> Indexed (catMaybes i)
|
|
|
|
|
Fixed i -> Fixed (catMaybes i)
|
|
|
|
|
Keyed i -> Keyed (Map.fromList (Map.toList i >>= (\ (k, v) -> maybe [] (pure . (,) k) v)))
|
|
|
|
|
|
2016-06-27 19:02:25 +03:00
|
|
|
|
beforeTerm :: Diff leaf annotation -> Maybe (Term leaf annotation)
|
2016-06-27 19:50:10 +03:00
|
|
|
|
beforeTerm = mergeMaybe before
|