module Data.Express.Triexpr
( Triexpr (..)
, empty
, unit
, merge
, insert
, toList
, fromList
, map
, lookup
)
where
import Data.Express.Core
import Data.Express.Match
import Data.Maybe
import Prelude hiding (map, lookup)
data Triexpr a = Triexpr [(Maybe Expr, Either (Triexpr a) (Expr,a))]
deriving (Triexpr a -> Triexpr a -> Bool
(Triexpr a -> Triexpr a -> Bool)
-> (Triexpr a -> Triexpr a -> Bool) -> Eq (Triexpr a)
forall a. Eq a => Triexpr a -> Triexpr a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Triexpr a -> Triexpr a -> Bool
$c/= :: forall a. Eq a => Triexpr a -> Triexpr a -> Bool
== :: Triexpr a -> Triexpr a -> Bool
$c== :: forall a. Eq a => Triexpr a -> Triexpr a -> Bool
Eq, Eq (Triexpr a)
Eq (Triexpr a)
-> (Triexpr a -> Triexpr a -> Ordering)
-> (Triexpr a -> Triexpr a -> Bool)
-> (Triexpr a -> Triexpr a -> Bool)
-> (Triexpr a -> Triexpr a -> Bool)
-> (Triexpr a -> Triexpr a -> Bool)
-> (Triexpr a -> Triexpr a -> Triexpr a)
-> (Triexpr a -> Triexpr a -> Triexpr a)
-> Ord (Triexpr a)
Triexpr a -> Triexpr a -> Bool
Triexpr a -> Triexpr a -> Ordering
Triexpr a -> Triexpr a -> Triexpr a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (Triexpr a)
forall a. Ord a => Triexpr a -> Triexpr a -> Bool
forall a. Ord a => Triexpr a -> Triexpr a -> Ordering
forall a. Ord a => Triexpr a -> Triexpr a -> Triexpr a
min :: Triexpr a -> Triexpr a -> Triexpr a
$cmin :: forall a. Ord a => Triexpr a -> Triexpr a -> Triexpr a
max :: Triexpr a -> Triexpr a -> Triexpr a
$cmax :: forall a. Ord a => Triexpr a -> Triexpr a -> Triexpr a
>= :: Triexpr a -> Triexpr a -> Bool
$c>= :: forall a. Ord a => Triexpr a -> Triexpr a -> Bool
> :: Triexpr a -> Triexpr a -> Bool
$c> :: forall a. Ord a => Triexpr a -> Triexpr a -> Bool
<= :: Triexpr a -> Triexpr a -> Bool
$c<= :: forall a. Ord a => Triexpr a -> Triexpr a -> Bool
< :: Triexpr a -> Triexpr a -> Bool
$c< :: forall a. Ord a => Triexpr a -> Triexpr a -> Bool
compare :: Triexpr a -> Triexpr a -> Ordering
$ccompare :: forall a. Ord a => Triexpr a -> Triexpr a -> Ordering
$cp1Ord :: forall a. Ord a => Eq (Triexpr a)
Ord, Int -> Triexpr a -> ShowS
[Triexpr a] -> ShowS
Triexpr a -> String
(Int -> Triexpr a -> ShowS)
-> (Triexpr a -> String)
-> ([Triexpr a] -> ShowS)
-> Show (Triexpr a)
forall a. Show a => Int -> Triexpr a -> ShowS
forall a. Show a => [Triexpr a] -> ShowS
forall a. Show a => Triexpr a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Triexpr a] -> ShowS
$cshowList :: forall a. Show a => [Triexpr a] -> ShowS
show :: Triexpr a -> String
$cshow :: forall a. Show a => Triexpr a -> String
showsPrec :: Int -> Triexpr a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Triexpr a -> ShowS
Show)
empty :: Triexpr a
empty :: Triexpr a
empty = [(Maybe Expr, Either (Triexpr a) (Expr, a))] -> Triexpr a
forall a. [(Maybe Expr, Either (Triexpr a) (Expr, a))] -> Triexpr a
Triexpr []
unit :: Expr -> a -> Triexpr a
unit :: Expr -> a -> Triexpr a
unit Expr
e a
x = Expr -> Either (Triexpr a) (Expr, a) -> Triexpr a
forall a. Expr -> Either (Triexpr a) (Expr, a) -> Triexpr a
u Expr
e ((Expr, a) -> Either (Triexpr a) (Expr, a)
forall a b. b -> Either a b
Right (Expr
e,a
x))
where
u :: Expr -> (Either (Triexpr a) (Expr,a)) -> Triexpr a
u :: Expr -> Either (Triexpr a) (Expr, a) -> Triexpr a
u (Expr
e1 :$ Expr
e2) Either (Triexpr a) (Expr, a)
et = [(Maybe Expr, Either (Triexpr a) (Expr, a))] -> Triexpr a
forall a. [(Maybe Expr, Either (Triexpr a) (Expr, a))] -> Triexpr a
Triexpr [(Maybe Expr
forall a. Maybe a
Nothing, Triexpr a -> Either (Triexpr a) (Expr, a)
forall a b. a -> Either a b
Left (Triexpr a -> Either (Triexpr a) (Expr, a))
-> Triexpr a -> Either (Triexpr a) (Expr, a)
forall a b. (a -> b) -> a -> b
$ Expr -> Either (Triexpr a) (Expr, a) -> Triexpr a
forall a. Expr -> Either (Triexpr a) (Expr, a) -> Triexpr a
u Expr
e1 (Either (Triexpr a) (Expr, a) -> Triexpr a)
-> Either (Triexpr a) (Expr, a) -> Triexpr a
forall a b. (a -> b) -> a -> b
$ Triexpr a -> Either (Triexpr a) (Expr, a)
forall a b. a -> Either a b
Left (Triexpr a -> Either (Triexpr a) (Expr, a))
-> Triexpr a -> Either (Triexpr a) (Expr, a)
forall a b. (a -> b) -> a -> b
$ Expr -> Either (Triexpr a) (Expr, a) -> Triexpr a
forall a. Expr -> Either (Triexpr a) (Expr, a) -> Triexpr a
u Expr
e2 Either (Triexpr a) (Expr, a)
et)]
u Expr
e Either (Triexpr a) (Expr, a)
et = [(Maybe Expr, Either (Triexpr a) (Expr, a))] -> Triexpr a
forall a. [(Maybe Expr, Either (Triexpr a) (Expr, a))] -> Triexpr a
Triexpr [(Expr -> Maybe Expr
forall a. a -> Maybe a
Just Expr
e, Either (Triexpr a) (Expr, a)
et)]
merge :: Triexpr a -> Triexpr a -> Triexpr a
merge :: Triexpr a -> Triexpr a -> Triexpr a
merge (Triexpr [(Maybe Expr, Either (Triexpr a) (Expr, a))]
ms1) (Triexpr [(Maybe Expr, Either (Triexpr a) (Expr, a))]
ms2) = [(Maybe Expr, Either (Triexpr a) (Expr, a))] -> Triexpr a
forall a. [(Maybe Expr, Either (Triexpr a) (Expr, a))] -> Triexpr a
Triexpr ([(Maybe Expr, Either (Triexpr a) (Expr, a))] -> Triexpr a)
-> [(Maybe Expr, Either (Triexpr a) (Expr, a))] -> Triexpr a
forall a b. (a -> b) -> a -> b
$ [(Maybe Expr, Either (Triexpr a) (Expr, a))]
-> [(Maybe Expr, Either (Triexpr a) (Expr, a))]
-> [(Maybe Expr, Either (Triexpr a) (Expr, a))]
forall a a b.
Ord a =>
[(a, Either (Triexpr a) b)]
-> [(a, Either (Triexpr a) b)] -> [(a, Either (Triexpr a) b)]
m [(Maybe Expr, Either (Triexpr a) (Expr, a))]
ms1 [(Maybe Expr, Either (Triexpr a) (Expr, a))]
ms2
where
m :: [(a, Either (Triexpr a) b)]
-> [(a, Either (Triexpr a) b)] -> [(a, Either (Triexpr a) b)]
m [] [(a, Either (Triexpr a) b)]
ms = [(a, Either (Triexpr a) b)]
ms
m [(a, Either (Triexpr a) b)]
ms [] = [(a, Either (Triexpr a) b)]
ms
m ((a
e1,Either (Triexpr a) b
mt1):[(a, Either (Triexpr a) b)]
ms1) ((a
e2,Either (Triexpr a) b
mt2):[(a, Either (Triexpr a) b)]
ms2) = case a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare a
e1 a
e2 of
Ordering
LT -> (a
e1,Either (Triexpr a) b
mt1) (a, Either (Triexpr a) b)
-> [(a, Either (Triexpr a) b)] -> [(a, Either (Triexpr a) b)]
forall a. a -> [a] -> [a]
: [(a, Either (Triexpr a) b)]
-> [(a, Either (Triexpr a) b)] -> [(a, Either (Triexpr a) b)]
m [(a, Either (Triexpr a) b)]
ms1 ((a
e2,Either (Triexpr a) b
mt2)(a, Either (Triexpr a) b)
-> [(a, Either (Triexpr a) b)] -> [(a, Either (Triexpr a) b)]
forall a. a -> [a] -> [a]
:[(a, Either (Triexpr a) b)]
ms2)
Ordering
GT -> (a
e2,Either (Triexpr a) b
mt2) (a, Either (Triexpr a) b)
-> [(a, Either (Triexpr a) b)] -> [(a, Either (Triexpr a) b)]
forall a. a -> [a] -> [a]
: [(a, Either (Triexpr a) b)]
-> [(a, Either (Triexpr a) b)] -> [(a, Either (Triexpr a) b)]
m ((a
e1,Either (Triexpr a) b
mt1)(a, Either (Triexpr a) b)
-> [(a, Either (Triexpr a) b)] -> [(a, Either (Triexpr a) b)]
forall a. a -> [a] -> [a]
:[(a, Either (Triexpr a) b)]
ms1) [(a, Either (Triexpr a) b)]
ms2
Ordering
EQ -> case (Either (Triexpr a) b
mt1,Either (Triexpr a) b
mt2) of
(Left Triexpr a
t1, Left Triexpr a
t2) -> (a
e1, Triexpr a -> Either (Triexpr a) b
forall a b. a -> Either a b
Left (Triexpr a -> Either (Triexpr a) b)
-> Triexpr a -> Either (Triexpr a) b
forall a b. (a -> b) -> a -> b
$ Triexpr a
t1 Triexpr a -> Triexpr a -> Triexpr a
forall a. Triexpr a -> Triexpr a -> Triexpr a
`merge` Triexpr a
t2) (a, Either (Triexpr a) b)
-> [(a, Either (Triexpr a) b)] -> [(a, Either (Triexpr a) b)]
forall a. a -> [a] -> [a]
: [(a, Either (Triexpr a) b)]
-> [(a, Either (Triexpr a) b)] -> [(a, Either (Triexpr a) b)]
m [(a, Either (Triexpr a) b)]
ms1 [(a, Either (Triexpr a) b)]
ms2
(Either (Triexpr a) b
_,Either (Triexpr a) b
_) -> (a
e1,Either (Triexpr a) b
mt1) (a, Either (Triexpr a) b)
-> [(a, Either (Triexpr a) b)] -> [(a, Either (Triexpr a) b)]
forall a. a -> [a] -> [a]
: (a
e2,Either (Triexpr a) b
mt2) (a, Either (Triexpr a) b)
-> [(a, Either (Triexpr a) b)] -> [(a, Either (Triexpr a) b)]
forall a. a -> [a] -> [a]
: [(a, Either (Triexpr a) b)]
-> [(a, Either (Triexpr a) b)] -> [(a, Either (Triexpr a) b)]
m [(a, Either (Triexpr a) b)]
ms1 [(a, Either (Triexpr a) b)]
ms2
insert :: Expr -> a -> Triexpr a -> Triexpr a
insert :: Expr -> a -> Triexpr a -> Triexpr a
insert Expr
e a
x Triexpr a
t = Expr -> a -> Triexpr a
forall a. Expr -> a -> Triexpr a
unit Expr
e a
x Triexpr a -> Triexpr a -> Triexpr a
forall a. Triexpr a -> Triexpr a -> Triexpr a
`merge` Triexpr a
t
toList :: Triexpr a -> [(Expr, a)]
toList :: Triexpr a -> [(Expr, a)]
toList (Triexpr [(Maybe Expr, Either (Triexpr a) (Expr, a))]
ms) = ((Maybe Expr, Either (Triexpr a) (Expr, a)) -> [(Expr, a)])
-> [(Maybe Expr, Either (Triexpr a) (Expr, a))] -> [(Expr, a)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Maybe Expr, Either (Triexpr a) (Expr, a)) -> [(Expr, a)]
forall a a. (a, Either (Triexpr a) (Expr, a)) -> [(Expr, a)]
to [(Maybe Expr, Either (Triexpr a) (Expr, a))]
ms
where
to :: (a, Either (Triexpr a) (Expr, a)) -> [(Expr, a)]
to (a
_, Right (Expr, a)
ex) = [(Expr, a)
ex]
to (a
_, Left Triexpr a
t) = Triexpr a -> [(Expr, a)]
forall a. Triexpr a -> [(Expr, a)]
toList Triexpr a
t
fromList :: [(Expr, a)] -> Triexpr a
fromList :: [(Expr, a)] -> Triexpr a
fromList = ((Expr, a) -> Triexpr a -> Triexpr a)
-> Triexpr a -> [(Expr, a)] -> Triexpr a
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ((Expr -> a -> Triexpr a -> Triexpr a)
-> (Expr, a) -> Triexpr a -> Triexpr a
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Expr -> a -> Triexpr a -> Triexpr a
forall a. Expr -> a -> Triexpr a -> Triexpr a
insert) Triexpr a
forall a. Triexpr a
empty
map :: (a -> b) -> Triexpr a -> Triexpr b
map :: (a -> b) -> Triexpr a -> Triexpr b
map a -> b
f (Triexpr [(Maybe Expr, Either (Triexpr a) (Expr, a))]
ms) = [(Maybe Expr, Either (Triexpr b) (Expr, b))] -> Triexpr b
forall a. [(Maybe Expr, Either (Triexpr a) (Expr, a))] -> Triexpr a
Triexpr [(Maybe Expr
ex, (Triexpr a -> Triexpr b)
-> ((Expr, a) -> (Expr, b))
-> Either (Triexpr a) (Expr, a)
-> Either (Triexpr b) (Expr, b)
forall a c b d. (a -> c) -> (b -> d) -> Either a b -> Either c d
mapEither ((a -> b) -> Triexpr a -> Triexpr b
forall a b. (a -> b) -> Triexpr a -> Triexpr b
map a -> b
f) ((a -> b) -> (Expr, a) -> (Expr, b)
forall a b c. (a -> b) -> (c, a) -> (c, b)
mapSnd a -> b
f) Either (Triexpr a) (Expr, a)
eth) | (Maybe Expr
ex, Either (Triexpr a) (Expr, a)
eth) <- [(Maybe Expr, Either (Triexpr a) (Expr, a))]
ms]
where
mapEither :: (a -> c) -> (b -> d) -> Either a b -> Either c d
mapEither :: (a -> c) -> (b -> d) -> Either a b -> Either c d
mapEither a -> c
f b -> d
g (Left a
x) = c -> Either c d
forall a b. a -> Either a b
Left (a -> c
f a
x)
mapEither a -> c
f b -> d
g (Right b
y) = d -> Either c d
forall a b. b -> Either a b
Right (b -> d
g b
y)
mapSnd :: (a -> b) -> (c,a) -> (c,b)
mapSnd :: (a -> b) -> (c, a) -> (c, b)
mapSnd a -> b
f (c
x,a
y) = (c
x, a -> b
f a
y)
lookup :: Expr -> Triexpr a -> [ (Expr, [(Expr,Expr)], a) ]
lookup :: Expr -> Triexpr a -> [(Expr, [(Expr, Expr)], a)]
lookup Expr
e Triexpr a
t = [(Expr
e, [(Expr, Expr)]
bs, a
x) | ([(Expr, Expr)]
bs, Right (Expr
e,a
x)) <- Maybe Expr
-> Triexpr a
-> [(Expr, Expr)]
-> [([(Expr, Expr)], Either (Triexpr a) (Expr, a))]
forall a.
Maybe Expr
-> Triexpr a
-> [(Expr, Expr)]
-> [([(Expr, Expr)], Either (Triexpr a) (Expr, a))]
look (Expr -> Maybe Expr
forall a. a -> Maybe a
Just Expr
e) Triexpr a
t []]
where
look :: Maybe Expr -> Triexpr a -> [(Expr, Expr)] -> [([(Expr,Expr)], Either (Triexpr a) (Expr,a))]
look :: Maybe Expr
-> Triexpr a
-> [(Expr, Expr)]
-> [([(Expr, Expr)], Either (Triexpr a) (Expr, a))]
look Maybe Expr
Nothing t :: Triexpr a
t@(Triexpr [(Maybe Expr, Either (Triexpr a) (Expr, a))]
ms) [(Expr, Expr)]
bs = [([(Expr, Expr)]
bs, Either (Triexpr a) (Expr, a)
mt) | (Maybe Expr
Nothing, Either (Triexpr a) (Expr, a)
mt) <- [(Maybe Expr, Either (Triexpr a) (Expr, a))]
ms]
look (Just Expr
e) t :: Triexpr a
t@(Triexpr [(Maybe Expr, Either (Triexpr a) (Expr, a))]
ms) [(Expr, Expr)]
bs = [([(Expr, Expr)]
bs', Either (Triexpr a) (Expr, a)
mt) | (Just Expr
e', Either (Triexpr a) (Expr, a)
mt) <- [(Maybe Expr, Either (Triexpr a) (Expr, a))]
ms, [(Expr, Expr)]
bs' <- Maybe [(Expr, Expr)] -> [[(Expr, Expr)]]
forall a. Maybe a -> [a]
maybeToList ([(Expr, Expr)] -> Expr -> Expr -> Maybe [(Expr, Expr)]
matchWith [(Expr, Expr)]
bs Expr
e Expr
e')]
[([(Expr, Expr)], Either (Triexpr a) (Expr, a))]
-> [([(Expr, Expr)], Either (Triexpr a) (Expr, a))]
-> [([(Expr, Expr)], Either (Triexpr a) (Expr, a))]
forall a. [a] -> [a] -> [a]
++ [([(Expr, Expr)], Either (Triexpr a) (Expr, a))
r | Expr
e1 :$ Expr
e2 <- [Expr
e]
, ([(Expr, Expr)]
bs1, Left Triexpr a
t1) <- Maybe Expr
-> Triexpr a
-> [(Expr, Expr)]
-> [([(Expr, Expr)], Either (Triexpr a) (Expr, a))]
forall a.
Maybe Expr
-> Triexpr a
-> [(Expr, Expr)]
-> [([(Expr, Expr)], Either (Triexpr a) (Expr, a))]
look Maybe Expr
forall a. Maybe a
Nothing Triexpr a
t [(Expr, Expr)]
bs
, ([(Expr, Expr)]
bs2, Left Triexpr a
t2) <- Maybe Expr
-> Triexpr a
-> [(Expr, Expr)]
-> [([(Expr, Expr)], Either (Triexpr a) (Expr, a))]
forall a.
Maybe Expr
-> Triexpr a
-> [(Expr, Expr)]
-> [([(Expr, Expr)], Either (Triexpr a) (Expr, a))]
look (Expr -> Maybe Expr
forall a. a -> Maybe a
Just Expr
e1) Triexpr a
t1 [(Expr, Expr)]
bs1
, ([(Expr, Expr)], Either (Triexpr a) (Expr, a))
r <- Maybe Expr
-> Triexpr a
-> [(Expr, Expr)]
-> [([(Expr, Expr)], Either (Triexpr a) (Expr, a))]
forall a.
Maybe Expr
-> Triexpr a
-> [(Expr, Expr)]
-> [([(Expr, Expr)], Either (Triexpr a) (Expr, a))]
look (Expr -> Maybe Expr
forall a. a -> Maybe a
Just Expr
e2) Triexpr a
t2 [(Expr, Expr)]
bs2]