1
1
mirror of https://github.com/github/semantic.git synced 2024-12-24 23:42:31 +03:00
semantic/src/Algorithm.hs

56 lines
2.0 KiB
Haskell
Raw Normal View History

{-# LANGUAGE GADTs, RankNTypes #-}
2015-11-18 03:20:52 +03:00
module Algorithm where
2015-11-18 03:24:01 +03:00
import Control.Monad.Free.Freer
import Data.These
import Prologue hiding (liftF)
2016-08-04 01:12:31 +03:00
2017-02-21 18:26:27 +03:00
-- | A single step in a diffing algorithm, parameterized by the types of terms, diffs, and the result of the applicable algorithm.
2017-02-21 18:25:25 +03:00
data AlgorithmF term diff result where
-- | Diff two terms with the choice of algorithm left to the interpreters discretion.
Diff :: term -> term -> AlgorithmF term diff diff
2017-02-21 18:38:10 +03:00
-- | Diff two terms recursively in O(n) time, resulting in a single diff node.
Linear :: term -> term -> AlgorithmF term diff diff
2017-02-21 18:38:10 +03:00
-- | Diff two lists of terms by each elements similarity in O(n³ log n), resulting in a list of diffs.
RWS :: [term] -> [term] -> AlgorithmF term diff [diff]
-- | Delete a term..
Delete :: term -> AlgorithmF term diff diff
-- | Insert a term.
Insert :: term -> AlgorithmF term diff diff
-- | Replace one term with another.
Replace :: term -> term -> AlgorithmF term diff diff
2015-11-18 03:24:01 +03:00
-- | The free applicative for 'AlgorithmF'. This enables us to construct diff values using <$> and <*> notation.
type Algorithm term diff = Freer (AlgorithmF term diff)
2016-08-04 19:08:34 +03:00
-- DSL
-- | Diff two terms without specifying the algorithm to be used.
diff :: term -> term -> Algorithm term diff diff
diff = (liftF .) . Diff
2017-02-23 20:30:26 +03:00
-- | Diff a These of terms without specifying the algorithm to be used.
diffThese :: These term term -> Algorithm term diff diff
diffThese = these byDeleting byInserting diff
-- | Diff two terms linearly.
linearly :: term -> term -> Algorithm term diff diff
linearly a b = liftF (Linear a b)
-- | Diff two terms using RWS.
byRWS :: [term] -> [term] -> Algorithm term diff [diff]
byRWS a b = liftF (RWS a b)
-- | Delete a term.
byDeleting :: term -> Algorithm term diff diff
byDeleting = liftF . Delete
-- | Insert a term.
byInserting :: term -> Algorithm term diff diff
byInserting = liftF . Insert
-- | Replace one term with another.
byReplacing :: term -> term -> Algorithm term diff diff
byReplacing = (liftF .) . Replace