1
1
mirror of https://github.com/github/semantic.git synced 2024-12-21 13:51:44 +03:00
semantic/src/Diff.hs

40 lines
1.8 KiB
Haskell
Raw Normal View History

{-# LANGUAGE TypeFamilies, TypeSynonymInstances #-}
2016-06-30 19:59:26 +03:00
{-# OPTIONS_GHC -fno-warn-orphans #-}
2015-11-18 00:25:36 +03:00
module Diff where
import Prologue
2016-05-03 22:50:38 +03:00
import Data.Functor.Foldable as Foldable
import Data.Functor.Both as Both
2016-07-23 00:38:10 +03:00
import Data.Mergeable
2015-11-18 05:23:53 +03:00
import Patch
2016-02-29 18:04:59 +03:00
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.
type DiffF f annotation = FreeF (TermF f (Both annotation)) (Patch (Term f annotation))
type Diff f annotation = Free (TermF f (Both annotation)) (Patch (Term f 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-06-30 19:59:26 +03:00
instance Functor f => Foldable.Foldable (Free f a) where project = runFree
instance Functor f => Foldable.Unfoldable (Free f a) where embed = free
2015-11-18 00:25:36 +03:00
diffSum :: (Prologue.Foldable f, Functor f) => (Patch (Term f annotation) -> Int) -> Diff f annotation -> Int
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 diffs patches.
diffCost :: (Prologue.Foldable f, Functor f) => Diff f annotation -> Int
2015-12-01 03:16:22 +03:00
diffCost = diffSum $ patchSum termSize
-- | Merge a diff using a function to provide the Term (in Maybe, to simplify recovery of the before/after state) for every Patch.
mergeMaybe :: (Functor f, Mergeable f) => (Patch (Term f annotation) -> Maybe (Term f annotation)) -> Diff f annotation -> Maybe (Term f annotation)
mergeMaybe transform = iter algebra . fmap transform
where algebra :: Mergeable f => TermF f (Both annotation) (Maybe (Term f annotation)) -> Maybe (Term f annotation)
algebra (annotations :< syntax) = cofree . (Both.fst annotations :<) <$> sequenceAlt syntax
2016-06-27 19:49:44 +03:00
-- | Recover the before state of a diff.
beforeTerm :: (Functor f, Mergeable f) => Diff f annotation -> Maybe (Term f annotation)
2016-06-27 19:50:10 +03:00
beforeTerm = mergeMaybe before
-- | Recover the after state of a diff.
afterTerm :: (Functor f, Mergeable f) => Diff f annotation -> Maybe (Term f annotation)
afterTerm = mergeMaybe after