@@ -1,26 +1,38 @@
1-- | Utilities for traversing heterogeneous trees. A heterogeneous tree is a
1-- | Utilities for traversing heterogeneous trees. A heterogeneous tree is a
2-- collection of datatypes that "contain" eachother in some form of tree
2-- collection of datatypes that "contain" eachother in some form of tree
3-- structure.
3-- structure.
5module OpenAPI.Checker.Trace
4module OpenAPI.Checker.Trace
6− ( Steppable(..)
5+ ( Steppable (..)
7− , Trace(..)
6+ , Trace (..)
9− , DiffTrace(..)
7+ , DiffTrace (..)
10 , catDiffTrace
8 , catDiffTrace
11 , _DiffTrace
9 , _DiffTrace
12− , AnItem(..)
10+ , AnItem (..)
23+import Control.Category
15import Control.Lens
24import Control.Lens
16import Data.Kind
25import Data.Kind
17import Data.Type.Equality
26import Data.Type.Equality
18import Type.Reflection
27import Type.Reflection
28+import Prelude hiding ((.))
20−class (Typeable a, Typeable b, Ord (Step a b))
31+ (Typeable a, Typeable b, Ord (Step a b)) =>
21− => Steppable (a :: k) (b :: k) where
32+ Steppable (a :: k) (b :: k)
22 -- | How to get from an @a@ node to a @b@ node
34 -- | How to get from an @a@ node to a @b@ node
23− data family Step (a :: k) (b :: k) :: Type
35+ data Step (a :: k) (b :: k) :: Type
25-- | How to get from an @a@ node to a @b@ node in possibly multiple steps. Like
37-- | How to get from an @a@ node to a @b@ node in possibly multiple steps. Like
26-- a list, but indexed. The list is in reverse because in practice we append
38-- a list, but indexed. The list is in reverse because in practice we append
@@ -28,8 +40,17 @@ class (Typeable a, Typeable b, Ord (Step a b))
28data Trace (a :: k) (b :: k) where
40data Trace (a :: k) (b :: k) where
29 Root :: Trace a a
41 Root :: Trace a a
30 Snoc :: Steppable b c => Trace a b -> !(Step b c) -> Trace a c
42 Snoc :: Steppable b c => Trace a b -> !(Step b c) -> Trace a c
31infixl 5 `Snoc`
44infixl 5 `Snoc`
46+step :: Steppable a b => Step a b -> Trace a b
47+step s = Root `Snoc` s
49+instance Category Trace where
52+ (Snoc ys y) . xs = Snoc (ys . xs) y
33typeRepRHS :: Typeable b => Trace a b -> TypeRep b
54typeRepRHS :: Typeable b => Trace a b -> TypeRep b
34typeRepRHS _ = typeRep
55typeRepRHS _ = typeRep
@@ -46,24 +67,19 @@ instance TestEquality (Trace a) where
46instance Eq (Trace a b) where
67instance Eq (Trace a b) where
47 Root == Root = True
68 Root == Root = True
48 Snoc xs x == Snoc ys y
69 Snoc xs x == Snoc ys y
49− | Just Refl <- testEquality (typeRepRHS xs) (typeRepRHS ys)
70+ | Just Refl <- testEquality (typeRepRHS xs) (typeRepRHS ys) =
50− = xs == ys && x == y
71+ xs == ys && x == y
51 _ == _ = False
72 _ == _ = False
53instance Ord (Trace a b) where
74instance Ord (Trace a b) where
54 compare Root Root = EQ
75 compare Root Root = EQ
55 compare Root (Snoc _ _) = LT
76 compare Root (Snoc _ _) = LT
56 compare (Snoc _ _) Root = GT
77 compare (Snoc _ _) Root = GT
57− compare (Snoc xs x) (Snoc ys y)
78+ compare (Snoc xs x) (Snoc ys y) =
58− = case testEquality (typeRepRHS xs) (typeRepRHS ys) of
79+ case testEquality (typeRepRHS xs) (typeRepRHS ys) of
59 Just Refl -> compare xs ys <> compare x y
80 Just Refl -> compare xs ys <> compare x y
60 Nothing -> compare (someTypeRep xs) (someTypeRep ys)
81 Nothing -> compare (someTypeRep xs) (someTypeRep ys)
62−catTrace :: Trace a b -> Trace b c -> Trace a c
64−catTrace xs (Snoc ys y) = Snoc (catTrace xs ys) y
67-- | Like a differece list, but indexed.
83-- | Like a differece list, but indexed.
68newtype DiffTrace (a :: k) (b :: k)
84newtype DiffTrace (a :: k) (b :: k)
69 = DiffTrace (forall c. Trace c a -> Trace c b)
85 = DiffTrace (forall c. Trace c a -> Trace c b)
@@ -72,30 +88,42 @@ catDiffTrace :: DiffTrace a b -> DiffTrace b c -> DiffTrace a c
72catDiffTrace (DiffTrace f) (DiffTrace g) = DiffTrace (g . f)
88catDiffTrace (DiffTrace f) (DiffTrace g) = DiffTrace (g . f)
74_DiffTrace :: Iso (DiffTrace a b) (DiffTrace c d) (Trace a b) (Trace c d)
90_DiffTrace :: Iso (DiffTrace a b) (DiffTrace c d) (Trace a b) (Trace c d)
75−_DiffTrace = dimap (\(DiffTrace f) -> f Root)
91+_DiffTrace = dimap (\(DiffTrace f) -> f Root) $
76− $ fmap $ \xs -> DiffTrace (`catTrace` xs)
92+ fmap $ \xs -> DiffTrace (>>> xs)
78-- | An item related to some path relative to the root @r@.
94-- | An item related to some path relative to the root @r@.
79data AnItem (f :: k -> Type) (r :: k) where
95data AnItem (f :: k -> Type) (r :: k) where
80 AnItem :: Ord (f a) => Trace r a -> !(f a) -> AnItem f r
96 AnItem :: Ord (f a) => Trace r a -> !(f a) -> AnItem f r
81− -- the Ord is yuck but we need it and it should be fine in monomorphic cases
98+-- the Ord is yuck but we need it and it should be fine in monomorphic cases
83instance Eq (AnItem f r) where
100instance Eq (AnItem f r) where
84 AnItem xs fx == AnItem ys fy
101 AnItem xs fx == AnItem ys fy
85− | Just Refl <- testEquality xs ys
102+ | Just Refl <- testEquality xs ys =
86− = xs == ys && fx == fy
103+ xs == ys && fx == fy
87 _ == _ = False
104 _ == _ = False
89instance Typeable r => Ord (AnItem f r) where
106instance Typeable r => Ord (AnItem f r) where
90− compare (AnItem xs fx) (AnItem ys fy)
107+ compare (AnItem xs fx) (AnItem ys fy) =
91− = case testEquality xs ys of
108+ case testEquality xs ys of
92 Just Refl -> compare xs ys <> compare fx fy
109 Just Refl -> compare xs ys <> compare fx fy
93 Nothing -> case xs of
110 Nothing -> case xs of
94− Root -> case ys of
111+ Root -> case ys of
95− Root -> compare (someTypeRep xs) (someTypeRep ys)
112+ Root -> compare (someTypeRep xs) (someTypeRep ys)
96 Snoc _ _ -> compare (someTypeRep xs) (someTypeRep ys)
113 Snoc _ _ -> compare (someTypeRep xs) (someTypeRep ys)
97 Snoc _ _ -> case ys of
114 Snoc _ _ -> case ys of
98− Root -> compare (someTypeRep xs) (someTypeRep ys)
115+ Root -> compare (someTypeRep xs) (someTypeRep ys)
99 Snoc _ _ -> compare (someTypeRep xs) (someTypeRep ys)
116 Snoc _ _ -> compare (someTypeRep xs) (someTypeRep ys)
118+data Traced r a = Traced {getTrace :: Trace r a, getTraced :: a}
120+mapTraced :: (Trace r a -> Trace r b) -> (a -> b) -> Traced r a -> Traced r b
121+mapTraced f g (Traced t a) = Traced (f t) (g a)
123+retrace :: (Trace r a -> Trace r' a) -> Traced r a -> Traced r' a
124+retrace f (Traced t a) = Traced (f t) a
126+deTraced :: Traced r a -> (Trace r a, a)
127+deTraced (Traced a b) = (a, b)
101-- type APath = AnItem Proxy
129-- type APath = AnItem Proxy