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:
parent
a7dc70f474
commit
939041c43a
@ -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).
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user