{-# LANGUAGE RankNTypes #-}
module Pattern.RepresentationMap
( RepresentationMap(..)
, compose
)
where
import Pattern.Core (Pattern, PatternKind, ScopeQuery, kindName)
data RepresentationMap v = RepresentationMap
{ forall v. RepresentationMap v -> String
repMapName :: String
, forall v. RepresentationMap v -> PatternKind v
repMapDomain :: PatternKind v
, forall v. RepresentationMap v -> PatternKind v
repMapCodomain :: PatternKind v
, forall v.
RepresentationMap v
-> forall (q :: * -> *).
ScopeQuery q v =>
q v -> Pattern v -> Pattern v
repMapForward :: forall q. ScopeQuery q v => q v -> Pattern v -> Pattern v
, forall v.
RepresentationMap v
-> forall (q :: * -> *).
ScopeQuery q v =>
q v -> Pattern v -> Pattern v
repMapInverse :: forall q. ScopeQuery q v => q v -> Pattern v -> Pattern v
, forall v.
RepresentationMap v
-> forall (q :: * -> *). ScopeQuery q v => q v -> Pattern v -> Bool
repMapRoundTrip :: forall q. ScopeQuery q v => q v -> Pattern v -> Bool
}
compose :: RepresentationMap v -> RepresentationMap v -> Either String (RepresentationMap v)
compose :: forall v.
RepresentationMap v
-> RepresentationMap v -> Either String (RepresentationMap v)
compose RepresentationMap v
m1 RepresentationMap v
m2
| PatternKind v -> String
forall v. PatternKind v -> String
kindName (RepresentationMap v -> PatternKind v
forall v. RepresentationMap v -> PatternKind v
repMapCodomain RepresentationMap v
m1) String -> String -> Bool
forall a. Eq a => a -> a -> Bool
/= PatternKind v -> String
forall v. PatternKind v -> String
kindName (RepresentationMap v -> PatternKind v
forall v. RepresentationMap v -> PatternKind v
repMapDomain RepresentationMap v
m2) =
String -> Either String (RepresentationMap v)
forall a b. a -> Either a b
Left (String -> Either String (RepresentationMap v))
-> String -> Either String (RepresentationMap v)
forall a b. (a -> b) -> a -> b
$
String
"compose: codomain of '" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> RepresentationMap v -> String
forall v. RepresentationMap v -> String
repMapName RepresentationMap v
m1
String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"' (" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> PatternKind v -> String
forall v. PatternKind v -> String
kindName (RepresentationMap v -> PatternKind v
forall v. RepresentationMap v -> PatternKind v
repMapCodomain RepresentationMap v
m1)
String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
") does not match domain of '" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> RepresentationMap v -> String
forall v. RepresentationMap v -> String
repMapName RepresentationMap v
m2
String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"' (" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> PatternKind v -> String
forall v. PatternKind v -> String
kindName (RepresentationMap v -> PatternKind v
forall v. RepresentationMap v -> PatternKind v
repMapDomain RepresentationMap v
m2) String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
")"
| Bool
otherwise =
RepresentationMap v -> Either String (RepresentationMap v)
forall a b. b -> Either a b
Right
RepresentationMap
{ repMapName :: String
repMapName = RepresentationMap v -> String
forall v. RepresentationMap v -> String
repMapName RepresentationMap v
m1 String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
" >>> " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> RepresentationMap v -> String
forall v. RepresentationMap v -> String
repMapName RepresentationMap v
m2
, repMapDomain :: PatternKind v
repMapDomain = RepresentationMap v -> PatternKind v
forall v. RepresentationMap v -> PatternKind v
repMapDomain RepresentationMap v
m1
, repMapCodomain :: PatternKind v
repMapCodomain = RepresentationMap v -> PatternKind v
forall v. RepresentationMap v -> PatternKind v
repMapCodomain RepresentationMap v
m2
, repMapForward :: forall (q :: * -> *).
ScopeQuery q v =>
q v -> Pattern v -> Pattern v
repMapForward = \q v
q Pattern v
p -> RepresentationMap v
-> forall (q :: * -> *).
ScopeQuery q v =>
q v -> Pattern v -> Pattern v
forall v.
RepresentationMap v
-> forall (q :: * -> *).
ScopeQuery q v =>
q v -> Pattern v -> Pattern v
repMapForward RepresentationMap v
m2 q v
q (RepresentationMap v
-> forall (q :: * -> *).
ScopeQuery q v =>
q v -> Pattern v -> Pattern v
forall v.
RepresentationMap v
-> forall (q :: * -> *).
ScopeQuery q v =>
q v -> Pattern v -> Pattern v
repMapForward RepresentationMap v
m1 q v
q Pattern v
p)
, repMapInverse :: forall (q :: * -> *).
ScopeQuery q v =>
q v -> Pattern v -> Pattern v
repMapInverse = \q v
q Pattern v
p -> RepresentationMap v
-> forall (q :: * -> *).
ScopeQuery q v =>
q v -> Pattern v -> Pattern v
forall v.
RepresentationMap v
-> forall (q :: * -> *).
ScopeQuery q v =>
q v -> Pattern v -> Pattern v
repMapInverse RepresentationMap v
m1 q v
q (RepresentationMap v
-> forall (q :: * -> *).
ScopeQuery q v =>
q v -> Pattern v -> Pattern v
forall v.
RepresentationMap v
-> forall (q :: * -> *).
ScopeQuery q v =>
q v -> Pattern v -> Pattern v
repMapInverse RepresentationMap v
m2 q v
q Pattern v
p)
, repMapRoundTrip :: forall (q :: * -> *). ScopeQuery q v => q v -> Pattern v -> Bool
repMapRoundTrip =
\q v
q Pattern v
p -> RepresentationMap v
-> forall (q :: * -> *). ScopeQuery q v => q v -> Pattern v -> Bool
forall v.
RepresentationMap v
-> forall (q :: * -> *). ScopeQuery q v => q v -> Pattern v -> Bool
repMapRoundTrip RepresentationMap v
m1 q v
q Pattern v
p Bool -> Bool -> Bool
&& RepresentationMap v
-> forall (q :: * -> *). ScopeQuery q v => q v -> Pattern v -> Bool
forall v.
RepresentationMap v
-> forall (q :: * -> *). ScopeQuery q v => q v -> Pattern v -> Bool
repMapRoundTrip RepresentationMap v
m2 q v
q (RepresentationMap v
-> forall (q :: * -> *).
ScopeQuery q v =>
q v -> Pattern v -> Pattern v
forall v.
RepresentationMap v
-> forall (q :: * -> *).
ScopeQuery q v =>
q v -> Pattern v -> Pattern v
repMapForward RepresentationMap v
m1 q v
q Pattern v
p)
}