module Control.Monad.Combinators.Expr
  ( Operator (..),
    makeExprParser,
  )
where
import Control.Monad
import Control.Monad.Combinators
data Operator m a
  = 
    InfixN (m (a -> a -> a))
  | 
    InfixL (m (a -> a -> a))
  | 
    InfixR (m (a -> a -> a))
  | 
    Prefix (m (a -> a))
  | 
    Postfix (m (a -> a))
  | 
    
    
    
    
    
    
    
    
    
    
    TernR (m (m (a -> a -> a -> a)))
makeExprParser ::
  MonadPlus m =>
  
  m a ->
  
  [[Operator m a]] ->
  
  m a
makeExprParser :: m a -> [[Operator m a]] -> m a
makeExprParser = (m a -> [Operator m a] -> m a) -> m a -> [[Operator m a]] -> m a
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl m a -> [Operator m a] -> m a
forall (m :: * -> *) a. MonadPlus m => m a -> [Operator m a] -> m a
addPrecLevel
{-# INLINEABLE makeExprParser #-}
addPrecLevel :: MonadPlus m => m a -> [Operator m a] -> m a
addPrecLevel :: m a -> [Operator m a] -> m a
addPrecLevel m a
term [Operator m a]
ops =
  m a
term' m a -> (a -> m a) -> m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \a
x -> [m a] -> m a
forall (f :: * -> *) (m :: * -> *) a.
(Foldable f, Alternative m) =>
f (m a) -> m a
choice [a -> m a
ras' a
x, a -> m a
las' a
x, a -> m a
nas' a
x, a -> m a
tern' a
x, a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
x]
  where
    ([m (a -> a -> a)]
ras, [m (a -> a -> a)]
las, [m (a -> a -> a)]
nas, [m (a -> a)]
prefix, [m (a -> a)]
postfix, [m (m (a -> a -> a -> a))]
tern) = (Operator m a
 -> ([m (a -> a -> a)], [m (a -> a -> a)], [m (a -> a -> a)],
     [m (a -> a)], [m (a -> a)], [m (m (a -> a -> a -> a))])
 -> ([m (a -> a -> a)], [m (a -> a -> a)], [m (a -> a -> a)],
     [m (a -> a)], [m (a -> a)], [m (m (a -> a -> a -> a))]))
-> ([m (a -> a -> a)], [m (a -> a -> a)], [m (a -> a -> a)],
    [m (a -> a)], [m (a -> a)], [m (m (a -> a -> a -> a))])
-> [Operator m a]
-> ([m (a -> a -> a)], [m (a -> a -> a)], [m (a -> a -> a)],
    [m (a -> a)], [m (a -> a)], [m (m (a -> a -> a -> a))])
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Operator m a
-> ([m (a -> a -> a)], [m (a -> a -> a)], [m (a -> a -> a)],
    [m (a -> a)], [m (a -> a)], [m (m (a -> a -> a -> a))])
-> ([m (a -> a -> a)], [m (a -> a -> a)], [m (a -> a -> a)],
    [m (a -> a)], [m (a -> a)], [m (m (a -> a -> a -> a))])
forall (m :: * -> *) a. Operator m a -> Batch m a -> Batch m a
splitOp ([], [], [], [], [], []) [Operator m a]
ops
    term' :: m a
term' = m (a -> a) -> m a -> m (a -> a) -> m a
forall (m :: * -> *) a.
MonadPlus m =>
m (a -> a) -> m a -> m (a -> a) -> m a
pTerm ([m (a -> a)] -> m (a -> a)
forall (f :: * -> *) (m :: * -> *) a.
(Foldable f, Alternative m) =>
f (m a) -> m a
choice [m (a -> a)]
prefix) m a
term ([m (a -> a)] -> m (a -> a)
forall (f :: * -> *) (m :: * -> *) a.
(Foldable f, Alternative m) =>
f (m a) -> m a
choice [m (a -> a)]
postfix)
    ras' :: a -> m a
ras' = m (a -> a -> a) -> m a -> a -> m a
forall (m :: * -> *) a.
MonadPlus m =>
m (a -> a -> a) -> m a -> a -> m a
pInfixR ([m (a -> a -> a)] -> m (a -> a -> a)
forall (f :: * -> *) (m :: * -> *) a.
(Foldable f, Alternative m) =>
f (m a) -> m a
choice [m (a -> a -> a)]
ras) m a
term'
    las' :: a -> m a
las' = m (a -> a -> a) -> m a -> a -> m a
forall (m :: * -> *) a.
MonadPlus m =>
m (a -> a -> a) -> m a -> a -> m a
pInfixL ([m (a -> a -> a)] -> m (a -> a -> a)
forall (f :: * -> *) (m :: * -> *) a.
(Foldable f, Alternative m) =>
f (m a) -> m a
choice [m (a -> a -> a)]
las) m a
term'
    nas' :: a -> m a
nas' = m (a -> a -> a) -> m a -> a -> m a
forall (m :: * -> *) a.
MonadPlus m =>
m (a -> a -> a) -> m a -> a -> m a
pInfixN ([m (a -> a -> a)] -> m (a -> a -> a)
forall (f :: * -> *) (m :: * -> *) a.
(Foldable f, Alternative m) =>
f (m a) -> m a
choice [m (a -> a -> a)]
nas) m a
term'
    tern' :: a -> m a
tern' = m (m (a -> a -> a -> a)) -> m a -> a -> m a
forall (m :: * -> *) a.
MonadPlus m =>
m (m (a -> a -> a -> a)) -> m a -> a -> m a
pTernR ([m (m (a -> a -> a -> a))] -> m (m (a -> a -> a -> a))
forall (f :: * -> *) (m :: * -> *) a.
(Foldable f, Alternative m) =>
f (m a) -> m a
choice [m (m (a -> a -> a -> a))]
tern) m a
term'
{-# INLINEABLE addPrecLevel #-}
pTerm :: MonadPlus m => m (a -> a) -> m a -> m (a -> a) -> m a
pTerm :: m (a -> a) -> m a -> m (a -> a) -> m a
pTerm m (a -> a)
prefix m a
term m (a -> a)
postfix = do
  a -> a
pre <- (a -> a) -> m (a -> a) -> m (a -> a)
forall (m :: * -> *) a. Alternative m => a -> m a -> m a
option a -> a
forall a. a -> a
id m (a -> a)
prefix
  a
x <- m a
term
  a -> a
post <- (a -> a) -> m (a -> a) -> m (a -> a)
forall (m :: * -> *) a. Alternative m => a -> m a -> m a
option a -> a
forall a. a -> a
id m (a -> a)
postfix
  a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> m a) -> (a -> a) -> a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
post (a -> a) -> (a -> a) -> a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
pre (a -> m a) -> a -> m a
forall a b. (a -> b) -> a -> b
$ a
x
{-# INLINE pTerm #-}
pInfixN :: MonadPlus m => m (a -> a -> a) -> m a -> a -> m a
pInfixN :: m (a -> a -> a) -> m a -> a -> m a
pInfixN m (a -> a -> a)
op m a
p a
x = do
  a -> a -> a
f <- m (a -> a -> a)
op
  a
y <- m a
p
  a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> m a) -> a -> m a
forall a b. (a -> b) -> a -> b
$ a -> a -> a
f a
x a
y
{-# INLINE pInfixN #-}
pInfixL :: MonadPlus m => m (a -> a -> a) -> m a -> a -> m a
pInfixL :: m (a -> a -> a) -> m a -> a -> m a
pInfixL m (a -> a -> a)
op m a
p a
x = do
  a -> a -> a
f <- m (a -> a -> a)
op
  a
y <- m a
p
  let r :: a
r = a -> a -> a
f a
x a
y
  m (a -> a -> a) -> m a -> a -> m a
forall (m :: * -> *) a.
MonadPlus m =>
m (a -> a -> a) -> m a -> a -> m a
pInfixL m (a -> a -> a)
op m a
p a
r m a -> m a -> m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
r
{-# INLINE pInfixL #-}
pInfixR :: MonadPlus m => m (a -> a -> a) -> m a -> a -> m a
pInfixR :: m (a -> a -> a) -> m a -> a -> m a
pInfixR m (a -> a -> a)
op m a
p a
x = do
  a -> a -> a
f <- m (a -> a -> a)
op
  a
y <- m a
p m a -> (a -> m a) -> m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \a
r -> m (a -> a -> a) -> m a -> a -> m a
forall (m :: * -> *) a.
MonadPlus m =>
m (a -> a -> a) -> m a -> a -> m a
pInfixR m (a -> a -> a)
op m a
p a
r m a -> m a -> m a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
r
  a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> m a) -> a -> m a
forall a b. (a -> b) -> a -> b
$ a -> a -> a
f a
x a
y
{-# INLINE pInfixR #-}
pTernR :: MonadPlus m => m (m (a -> a -> a -> a)) -> m a -> a -> m a
pTernR :: m (m (a -> a -> a -> a)) -> m a -> a -> m a
pTernR m (m (a -> a -> a -> a))
sep1 m a
p a
x = do
  m (a -> a -> a -> a)
sep2 <- m (m (a -> a -> a -> a))
sep1
  a
y <- m a
p m a -> (a -> m a) -> m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \a
r -> m (m (a -> a -> a -> a)) -> m a -> a -> m a
forall (m :: * -> *) a.
MonadPlus m =>
m (m (a -> a -> a -> a)) -> m a -> a -> m a
pTernR m (m (a -> a -> a -> a))
sep1 m a
p a
r m a -> m a -> m a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
r
  a -> a -> a -> a
f <- m (a -> a -> a -> a)
sep2
  a
z <- m a
p m a -> (a -> m a) -> m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \a
r -> m (m (a -> a -> a -> a)) -> m a -> a -> m a
forall (m :: * -> *) a.
MonadPlus m =>
m (m (a -> a -> a -> a)) -> m a -> a -> m a
pTernR m (m (a -> a -> a -> a))
sep1 m a
p a
r m a -> m a -> m a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
r
  a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> m a) -> a -> m a
forall a b. (a -> b) -> a -> b
$ a -> a -> a -> a
f a
x a
y a
z
{-# INLINE pTernR #-}
type Batch m a =
  ( [m (a -> a -> a)],
    [m (a -> a -> a)],
    [m (a -> a -> a)],
    [m (a -> a)],
    [m (a -> a)],
    [m (m (a -> a -> a -> a))]
  )
splitOp :: Operator m a -> Batch m a -> Batch m a
splitOp :: Operator m a -> Batch m a -> Batch m a
splitOp (InfixR m (a -> a -> a)
op) ([m (a -> a -> a)]
r, [m (a -> a -> a)]
l, [m (a -> a -> a)]
n, [m (a -> a)]
pre, [m (a -> a)]
post, [m (m (a -> a -> a -> a))]
tern) = (m (a -> a -> a)
op m (a -> a -> a) -> [m (a -> a -> a)] -> [m (a -> a -> a)]
forall a. a -> [a] -> [a]
: [m (a -> a -> a)]
r, [m (a -> a -> a)]
l, [m (a -> a -> a)]
n, [m (a -> a)]
pre, [m (a -> a)]
post, [m (m (a -> a -> a -> a))]
tern)
splitOp (InfixL m (a -> a -> a)
op) ([m (a -> a -> a)]
r, [m (a -> a -> a)]
l, [m (a -> a -> a)]
n, [m (a -> a)]
pre, [m (a -> a)]
post, [m (m (a -> a -> a -> a))]
tern) = ([m (a -> a -> a)]
r, m (a -> a -> a)
op m (a -> a -> a) -> [m (a -> a -> a)] -> [m (a -> a -> a)]
forall a. a -> [a] -> [a]
: [m (a -> a -> a)]
l, [m (a -> a -> a)]
n, [m (a -> a)]
pre, [m (a -> a)]
post, [m (m (a -> a -> a -> a))]
tern)
splitOp (InfixN m (a -> a -> a)
op) ([m (a -> a -> a)]
r, [m (a -> a -> a)]
l, [m (a -> a -> a)]
n, [m (a -> a)]
pre, [m (a -> a)]
post, [m (m (a -> a -> a -> a))]
tern) = ([m (a -> a -> a)]
r, [m (a -> a -> a)]
l, m (a -> a -> a)
op m (a -> a -> a) -> [m (a -> a -> a)] -> [m (a -> a -> a)]
forall a. a -> [a] -> [a]
: [m (a -> a -> a)]
n, [m (a -> a)]
pre, [m (a -> a)]
post, [m (m (a -> a -> a -> a))]
tern)
splitOp (Prefix m (a -> a)
op) ([m (a -> a -> a)]
r, [m (a -> a -> a)]
l, [m (a -> a -> a)]
n, [m (a -> a)]
pre, [m (a -> a)]
post, [m (m (a -> a -> a -> a))]
tern) = ([m (a -> a -> a)]
r, [m (a -> a -> a)]
l, [m (a -> a -> a)]
n, m (a -> a)
op m (a -> a) -> [m (a -> a)] -> [m (a -> a)]
forall a. a -> [a] -> [a]
: [m (a -> a)]
pre, [m (a -> a)]
post, [m (m (a -> a -> a -> a))]
tern)
splitOp (Postfix m (a -> a)
op) ([m (a -> a -> a)]
r, [m (a -> a -> a)]
l, [m (a -> a -> a)]
n, [m (a -> a)]
pre, [m (a -> a)]
post, [m (m (a -> a -> a -> a))]
tern) = ([m (a -> a -> a)]
r, [m (a -> a -> a)]
l, [m (a -> a -> a)]
n, [m (a -> a)]
pre, m (a -> a)
op m (a -> a) -> [m (a -> a)] -> [m (a -> a)]
forall a. a -> [a] -> [a]
: [m (a -> a)]
post, [m (m (a -> a -> a -> a))]
tern)
splitOp (TernR m (m (a -> a -> a -> a))
op) ([m (a -> a -> a)]
r, [m (a -> a -> a)]
l, [m (a -> a -> a)]
n, [m (a -> a)]
pre, [m (a -> a)]
post, [m (m (a -> a -> a -> a))]
tern) = ([m (a -> a -> a)]
r, [m (a -> a -> a)]
l, [m (a -> a -> a)]
n, [m (a -> a)]
pre, [m (a -> a)]
post, m (m (a -> a -> a -> a))
op m (m (a -> a -> a -> a))
-> [m (m (a -> a -> a -> a))] -> [m (m (a -> a -> a -> a))]
forall a. a -> [a] -> [a]
: [m (m (a -> a -> a -> a))]
tern)