{-# LANGUAGE UndecidableInstances #-}
module Control.Effect.Choose
(
Choose(..)
, (<|>)
, optional
, many
, some
, some1
, Choosing(..)
, Algebra
, Has
, run
) where
import Control.Algebra
import Control.Effect.Choose.Internal (Choose(..))
import Control.Effect.Empty
import Data.Bool (bool)
import Data.List.NonEmpty (NonEmpty(..))
import qualified Data.Semigroup as S
(<|>) :: Has Choose sig m => m a -> m a -> m a
m a
a <|> :: forall (sig :: (* -> *) -> * -> *) (m :: * -> *) a.
Has Choose sig m =>
m a -> m a -> m a
<|> m a
b = Choose m Bool -> m Bool
forall (eff :: (* -> *) -> * -> *) (sig :: (* -> *) -> * -> *)
(m :: * -> *) a.
(Member eff sig, Algebra sig m) =>
eff m a -> m a
send Choose m Bool
forall (m :: * -> *). Choose m Bool
Choose m Bool -> (Bool -> m a) -> m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= m a -> m a -> Bool -> m a
forall a. a -> a -> Bool -> a
bool m a
b m a
a
{-# INLINE (<|>) #-}
infixl 3 <|>
optional :: Has Choose sig m => m a -> m (Maybe a)
optional :: forall (sig :: (* -> *) -> * -> *) (m :: * -> *) a.
Has Choose sig m =>
m a -> m (Maybe a)
optional m a
a = a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> m a -> m (Maybe a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m a
a m (Maybe a) -> m (Maybe a) -> m (Maybe a)
forall (sig :: (* -> *) -> * -> *) (m :: * -> *) a.
Has Choose sig m =>
m a -> m a -> m a
<|> Maybe a -> m (Maybe a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe a
forall a. Maybe a
Nothing
{-# INLINE optional #-}
many :: Has Choose sig m => m a -> m [a]
many :: forall (sig :: (* -> *) -> * -> *) (m :: * -> *) a.
Has Choose sig m =>
m a -> m [a]
many m a
a = m [a]
go where go :: m [a]
go = (:) (a -> [a] -> [a]) -> m a -> m ([a] -> [a])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m a
a m ([a] -> [a]) -> m [a] -> m [a]
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m [a]
go m [a] -> m [a] -> m [a]
forall (sig :: (* -> *) -> * -> *) (m :: * -> *) a.
Has Choose sig m =>
m a -> m a -> m a
<|> [a] -> m [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
{-# INLINE many #-}
some :: Has Choose sig m => m a -> m [a]
some :: forall (sig :: (* -> *) -> * -> *) (m :: * -> *) a.
Has Choose sig m =>
m a -> m [a]
some m a
a = (:) (a -> [a] -> [a]) -> m a -> m ([a] -> [a])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m a
a m ([a] -> [a]) -> m [a] -> m [a]
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a -> m [a]
forall (sig :: (* -> *) -> * -> *) (m :: * -> *) a.
Has Choose sig m =>
m a -> m [a]
many m a
a
{-# INLINE some #-}
some1 :: Has Choose sig m => m a -> m (NonEmpty a)
some1 :: forall (sig :: (* -> *) -> * -> *) (m :: * -> *) a.
Has Choose sig m =>
m a -> m (NonEmpty a)
some1 m a
a = a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
(:|) (a -> [a] -> NonEmpty a) -> m a -> m ([a] -> NonEmpty a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m a
a m ([a] -> NonEmpty a) -> m [a] -> m (NonEmpty a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m a -> m [a]
forall (sig :: (* -> *) -> * -> *) (m :: * -> *) a.
Has Choose sig m =>
m a -> m [a]
many m a
a
{-# INLINE some1 #-}
newtype Choosing m a = Choosing { forall (m :: * -> *) a. Choosing m a -> m a
getChoosing :: m a }
instance Has Choose sig m => S.Semigroup (Choosing m a) where
Choosing m a
m1 <> :: Choosing m a -> Choosing m a -> Choosing m a
<> Choosing m a
m2 = m a -> Choosing m a
forall (m :: * -> *) a. m a -> Choosing m a
Choosing (m a
m1 m a -> m a -> m a
forall (sig :: (* -> *) -> * -> *) (m :: * -> *) a.
Has Choose sig m =>
m a -> m a -> m a
<|> m a
m2)
{-# INLINE (<>) #-}
instance (Has Choose sig m, Has Empty sig m) => Monoid (Choosing m a) where
mempty :: Choosing m a
mempty = m a -> Choosing m a
forall (m :: * -> *) a. m a -> Choosing m a
Choosing m a
forall (sig :: (* -> *) -> * -> *) (m :: * -> *) a.
Has Empty sig m =>
m a
empty
{-# INLINE mempty #-}
mappend :: Choosing m a -> Choosing m a -> Choosing m a
mappend = Choosing m a -> Choosing m a -> Choosing m a
forall a. Semigroup a => a -> a -> a
(S.<>)
{-# INLINE mappend #-}