1
1
mirror of https://github.com/github/semantic.git synced 2024-12-01 09:15:01 +03:00

tryAlignWith uses Edit.

This commit is contained in:
Rob Rix 2019-10-18 11:25:02 -04:00
parent a7dc70f474
commit 939041c43a
No known key found for this signature in database
GPG Key ID: F188A01508EA1CF7
3 changed files with 18 additions and 18 deletions

View File

@ -54,7 +54,7 @@ instance Carrier sig m => Carrier sig (Algorithm term1 term2 diff m) where
diff :: (Carrier sig m, Member (Diff term1 term2 diff) sig) => term1 -> term2 -> m diff
diff a1 a2 = send (Diff a1 a2 pure)
-- | Diff an 'Edit' of terms without specifying the algorithm to be used.
-- | Diff an 'Edit.Edit' of terms without specifying the algorithm to be used.
diffEdit :: (Carrier sig m, Member (Diff term1 term2 diff) sig) => Edit.Edit term1 term2 -> Algorithm term1 term2 diff m diff
diffEdit = Edit.edit byDeleting byInserting diff
@ -144,8 +144,8 @@ class Diffable f where
-> Algorithm term1 term2 diff m (f diff)
algorithmFor = genericAlgorithmFor
tryAlignWith :: Alternative g => (These a1 a2 -> g b) -> f a1 -> f a2 -> g (f b)
default tryAlignWith :: (Alternative g, Generic1 f, GDiffable (Rep1 f)) => (These a1 a2 -> g b) -> f a1 -> f a2 -> g (f b)
tryAlignWith :: Alternative g => (Edit.Edit a1 a2 -> g b) -> f a1 -> f a2 -> g (f b)
default tryAlignWith :: (Alternative g, Generic1 f, GDiffable (Rep1 f)) => (Edit.Edit a1 a2 -> g b) -> f a1 -> f a2 -> g (f b)
tryAlignWith f a b = to1 <$> gtryAlignWith f (from1 a) (from1 b)
-- | Construct an algorithm to diff against positions inside an @f@.
@ -208,30 +208,30 @@ instance Apply Diffable fs => Diffable (Sum fs) where
instance Diffable Maybe where
algorithmFor = diffMaybe
tryAlignWith f (Just a1) (Just a2) = Just <$> f (These a1 a2)
tryAlignWith f (Just a1) Nothing = Just <$> f (This a1)
tryAlignWith f Nothing (Just a2) = Just <$> f (That a2)
tryAlignWith f (Just a1) (Just a2) = Just <$> f (Edit.Compare a1 a2)
tryAlignWith f (Just a1) Nothing = Just <$> f (Edit.Delete a1)
tryAlignWith f Nothing (Just a2) = Just <$> f (Edit.Insert a2)
tryAlignWith _ Nothing Nothing = pure Nothing
-- | Diff two lists using RWS.
instance Diffable [] where
algorithmFor = byRWS
tryAlignWith f (a1:as1) (a2:as2) = (:) <$> f (These a1 a2) <*> tryAlignWith f as1 as2
tryAlignWith f [] as2 = traverse (f . That) as2
tryAlignWith f as1 [] = traverse (f . This) as1
tryAlignWith f (a1:as1) (a2:as2) = (:) <$> f (Edit.Compare a1 a2) <*> tryAlignWith f as1 as2
tryAlignWith f [] as2 = traverse (f . Edit.Insert) as2
tryAlignWith f as1 [] = traverse (f . Edit.Delete) as1
-- | Diff two non-empty lists using RWS.
instance Diffable NonEmpty where
algorithmFor (a1:|as1) (a2:|as2) = nonEmpty <$> byRWS (a1:as1) (a2:as2) >>= maybeM empty
tryAlignWith f (a1:|as1) (a2:|as2) = (:|) <$> f (These a1 a2) <*> tryAlignWith f as1 as2
tryAlignWith f (a1:|as1) (a2:|as2) = (:|) <$> f (Edit.Compare a1 a2) <*> tryAlignWith f as1 as2
-- | A generic type class for diffing two terms defined by the Generic1 interface.
class GDiffable f where
galgorithmFor :: (Alternative m, Carrier sig m, Member (Diff term1 term2 diff) sig, Member NonDet sig) => f term1 -> f term2 -> Algorithm term1 term2 diff m (f diff)
gtryAlignWith :: Alternative g => (These a1 a2 -> g b) -> f a1 -> f a2 -> g (f b)
gtryAlignWith :: Alternative g => (Edit.Edit a1 a2 -> g b) -> f a1 -> f a2 -> g (f b)
gcomparableTo :: f term1 -> f term2 -> Bool
gcomparableTo _ _ = True
@ -272,7 +272,7 @@ instance (GDiffable f, GDiffable g) => GDiffable (f :+: g) where
instance GDiffable Par1 where
galgorithmFor (Par1 a1) (Par1 a2) = Par1 <$> diff a1 a2
gtryAlignWith f (Par1 a) (Par1 b) = Par1 <$> f (These a b)
gtryAlignWith f (Par1 a) (Par1 b) = Par1 <$> f (Edit.Compare a b)
-- | Diff two constant parameters (K1 is the Generic1 newtype representing type parameter constants).
-- i.e. data Foo = Foo Int (the 'Int' is a constant parameter).

View File

@ -159,7 +159,7 @@ editDistanceUpTo m a b = diffCost m (approximateDiff a b)
_ | m <= 0 -> 0
Merge body -> sum (fmap ($ pred m) body)
body -> succ (sum (fmap ($ pred m) body))
approximateDiff a b = maybe (comparing a b) (merge (termAnnotation a, termAnnotation b)) (tryAlignWith (Just . these deleting inserting approximateDiff) (termOut a) (termOut b))
approximateDiff a b = maybe (comparing a b) (merge (termAnnotation a, termAnnotation b)) (tryAlignWith (Just . edit deleting inserting approximateDiff) (termOut a) (termOut b))
data Label syntax where

View File

@ -9,7 +9,7 @@ import Control.Effect.Carrier
import Control.Effect.Cull
import Control.Effect.NonDet
import qualified Data.Diff as Diff
import qualified Data.Edit as Edit
import Data.Edit (Edit, edit)
import Data.Term
import Diffing.Algorithm
import Diffing.Algorithm.RWS
@ -37,12 +37,12 @@ class Bifoldable (DiffFor term) => DiffTerms term where
-- Note that the dependency means that the diff type is in 1:1 correspondence with the term type. This allows subclasses of 'DiffTerms' to receive e.g. @'DiffFor' term a b@ without incurring ambiguity, since every diff type is unique to its term type.
type DiffFor term = (diff :: * -> * -> *) | diff -> term
-- | Diff an 'Edit.Edit' of terms.
diffTermPair :: Edit.Edit (term ann1) (term ann2) -> DiffFor term ann1 ann2
-- | Diff an 'Edit' of terms.
diffTermPair :: Edit (term ann1) (term ann2) -> DiffFor term ann1 ann2
instance (Diffable syntax, Eq1 syntax, Hashable1 syntax, Traversable syntax) => DiffTerms (Term syntax) where
type DiffFor (Term syntax) = Diff.Diff syntax
diffTermPair = Edit.edit Diff.deleting Diff.inserting diffTerms
diffTermPair = edit Diff.deleting Diff.inserting diffTerms
-- | Run an 'Algorithm' to completion in an 'Alternative' context using the supplied comparability & equivalence relations.
@ -72,7 +72,7 @@ instance ( Alternative m
(DiffC (Term syntax (FeatureVector, ann1)) (Term syntax (FeatureVector, ann2)) (Diff.Diff syntax (FeatureVector, ann1) (FeatureVector, ann2)) m) where
eff (L op) = case op of
Diff t1 t2 k -> runDiff (algorithmForTerms t1 t2) <|> pure (Diff.comparing t1 t2) >>= k
Linear (Term (In ann1 f1)) (Term (In ann2 f2)) k -> Diff.merge (ann1, ann2) <$> tryAlignWith (runDiff . diffEdit . these Edit.Delete Edit.Insert Edit.Compare) f1 f2 >>= k
Linear (Term (In ann1 f1)) (Term (In ann2 f2)) k -> Diff.merge (ann1, ann2) <$> tryAlignWith (runDiff . diffEdit) f1 f2 >>= k
RWS as bs k -> traverse (runDiff . diffEdit) (rws comparableTerms equivalentTerms as bs) >>= k
Delete a k -> k (Diff.deleting a)
Insert b k -> k (Diff.inserting b)