{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Control.Carrier.Choose.Church
(
runChoose
, runChooseS
, ChooseC(..)
, module Control.Effect.Choose
) where
import Control.Algebra
import Control.Applicative (liftA2)
import Control.Effect.Choose
import Control.Monad.Fail as Fail
import Control.Monad.Fix
import Control.Monad.IO.Class
import Control.Monad.Trans.Class
import Data.Coerce (coerce)
import Data.Functor.Identity
import Data.List.NonEmpty (NonEmpty(..), head, tail)
import Data.Semigroup as S
import Prelude hiding (head, tail)
runChoose :: (m b -> m b -> m b) -> (a -> m b) -> ChooseC m a -> m b
runChoose :: forall (m :: * -> *) b a.
(m b -> m b -> m b) -> (a -> m b) -> ChooseC m a -> m b
runChoose m b -> m b -> m b
fork a -> m b
leaf (ChooseC forall b. (m b -> m b -> m b) -> (a -> m b) -> m b
runChooseC) = forall b. (m b -> m b -> m b) -> (a -> m b) -> m b
runChooseC m b -> m b -> m b
fork a -> m b
leaf
{-# INLINE runChoose #-}
runChooseS :: (S.Semigroup b, Applicative m) => (a -> m b) -> ChooseC m a -> m b
runChooseS :: forall b (m :: * -> *) a.
(Semigroup b, Applicative m) =>
(a -> m b) -> ChooseC m a -> m b
runChooseS = forall (m :: * -> *) b a.
(m b -> m b -> m b) -> (a -> m b) -> ChooseC m a -> m b
runChoose (forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 forall a. Semigroup a => a -> a -> a
(S.<>))
{-# INLINE runChooseS #-}
newtype ChooseC m a = ChooseC (forall b . (m b -> m b -> m b) -> (a -> m b) -> m b)
deriving (forall a b. a -> ChooseC m b -> ChooseC m a
forall a b. (a -> b) -> ChooseC m a -> ChooseC m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
forall (m :: * -> *) a b. a -> ChooseC m b -> ChooseC m a
forall (m :: * -> *) a b. (a -> b) -> ChooseC m a -> ChooseC m b
<$ :: forall a b. a -> ChooseC m b -> ChooseC m a
$c<$ :: forall (m :: * -> *) a b. a -> ChooseC m b -> ChooseC m a
fmap :: forall a b. (a -> b) -> ChooseC m a -> ChooseC m b
$cfmap :: forall (m :: * -> *) a b. (a -> b) -> ChooseC m a -> ChooseC m b
Functor)
instance Applicative (ChooseC m) where
pure :: forall a. a -> ChooseC m a
pure a
a = forall (m :: * -> *) a.
(forall b. (m b -> m b -> m b) -> (a -> m b) -> m b) -> ChooseC m a
ChooseC (\ m b -> m b -> m b
_ a -> m b
leaf -> a -> m b
leaf a
a)
{-# INLINE pure #-}
ChooseC forall b. (m b -> m b -> m b) -> ((a -> b) -> m b) -> m b
f <*> :: forall a b. ChooseC m (a -> b) -> ChooseC m a -> ChooseC m b
<*> ChooseC forall b. (m b -> m b -> m b) -> (a -> m b) -> m b
a = forall (m :: * -> *) a.
(forall b. (m b -> m b -> m b) -> (a -> m b) -> m b) -> ChooseC m a
ChooseC forall a b. (a -> b) -> a -> b
$ \ m b -> m b -> m b
fork b -> m b
leaf ->
forall b. (m b -> m b -> m b) -> ((a -> b) -> m b) -> m b
f m b -> m b -> m b
fork (\ a -> b
f' -> forall b. (m b -> m b -> m b) -> (a -> m b) -> m b
a m b -> m b -> m b
fork (b -> m b
leaf forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f'))
{-# INLINE (<*>) #-}
instance Monad (ChooseC m) where
ChooseC forall b. (m b -> m b -> m b) -> (a -> m b) -> m b
a >>= :: forall a b. ChooseC m a -> (a -> ChooseC m b) -> ChooseC m b
>>= a -> ChooseC m b
f = forall (m :: * -> *) a.
(forall b. (m b -> m b -> m b) -> (a -> m b) -> m b) -> ChooseC m a
ChooseC forall a b. (a -> b) -> a -> b
$ \ m b -> m b -> m b
fork b -> m b
leaf ->
forall b. (m b -> m b -> m b) -> (a -> m b) -> m b
a m b -> m b -> m b
fork (forall (m :: * -> *) b a.
(m b -> m b -> m b) -> (a -> m b) -> ChooseC m a -> m b
runChoose m b -> m b -> m b
fork b -> m b
leaf forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> ChooseC m b
f)
{-# INLINE (>>=) #-}
instance Fail.MonadFail m => Fail.MonadFail (ChooseC m) where
fail :: forall a. String -> ChooseC m a
fail String
s = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (forall (m :: * -> *) a. MonadFail m => String -> m a
Fail.fail String
s)
{-# INLINE fail #-}
instance MonadFix m => MonadFix (ChooseC m) where
mfix :: forall a. (a -> ChooseC m a) -> ChooseC m a
mfix a -> ChooseC m a
f = forall (m :: * -> *) a.
(forall b. (m b -> m b -> m b) -> (a -> m b) -> m b) -> ChooseC m a
ChooseC forall a b. (a -> b) -> a -> b
$ \ m b -> m b -> m b
fork a -> m b
leaf ->
forall (m :: * -> *) a. MonadFix m => (a -> m a) -> m a
mfix (forall b (m :: * -> *) a.
(Semigroup b, Applicative m) =>
(a -> m b) -> ChooseC m a -> m b
runChooseS (forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a. Applicative f => a -> f a
pure) forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> ChooseC m a
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. NonEmpty a -> a
head)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
a
a:|[] -> a -> m b
leaf a
a
a
a:|[a]
_ -> a -> m b
leaf a
a m b -> m b -> m b
`fork` forall (m :: * -> *) b a.
(m b -> m b -> m b) -> (a -> m b) -> ChooseC m a -> m b
runChoose m b -> m b -> m b
fork a -> m b
leaf (forall (m :: * -> *) a. MonadFix m => (a -> m a) -> m a
mfix (forall {m :: * -> *} {t :: * -> *} {a}.
(Monad m, Foldable t, Functor t) =>
m (t a) -> ChooseC m a
liftAll forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. NonEmpty a -> [a]
tail forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b (m :: * -> *) a.
(Semigroup b, Applicative m) =>
(a -> m b) -> ChooseC m a -> m b
runChooseS (forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a. Applicative f => a -> f a
pure) forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> ChooseC m a
f))
where
liftAll :: m (t a) -> ChooseC m a
liftAll m (t a)
m = forall (m :: * -> *) a.
(forall b. (m b -> m b -> m b) -> (a -> m b) -> m b) -> ChooseC m a
ChooseC forall a b. (a -> b) -> a -> b
$ \ m b -> m b -> m b
fork a -> m b
leaf -> m (t a)
m forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 m b -> m b -> m b
fork forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> m b
leaf
{-# INLINE mfix #-}
instance MonadIO m => MonadIO (ChooseC m) where
liftIO :: forall a. IO a -> ChooseC m a
liftIO IO a
io = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO a
io)
{-# INLINE liftIO #-}
instance MonadTrans ChooseC where
lift :: forall (m :: * -> *) a. Monad m => m a -> ChooseC m a
lift m a
m = forall (m :: * -> *) a.
(forall b. (m b -> m b -> m b) -> (a -> m b) -> m b) -> ChooseC m a
ChooseC (\ m b -> m b -> m b
_ a -> m b
leaf -> m a
m forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= a -> m b
leaf)
{-# INLINE lift #-}
instance Algebra sig m => Algebra (Choose :+: sig) (ChooseC m) where
alg :: forall (ctx :: * -> *) (n :: * -> *) a.
Functor ctx =>
Handler ctx n (ChooseC m)
-> (:+:) Choose sig n a -> ctx () -> ChooseC m (ctx a)
alg Handler ctx n (ChooseC m)
hdl (:+:) Choose sig n a
sig ctx ()
ctx = forall (m :: * -> *) a.
(forall b. (m b -> m b -> m b) -> (a -> m b) -> m b) -> ChooseC m a
ChooseC forall a b. (a -> b) -> a -> b
$ \ m b -> m b -> m b
fork ctx a -> m b
leaf -> case (:+:) Choose sig n a
sig of
L Choose n a
Choose -> ctx a -> m b
leaf (Bool
True forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ ctx ()
ctx) m b -> m b -> m b
`fork` ctx a -> m b
leaf (Bool
False forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ ctx ()
ctx)
R sig n a
other -> forall (ctx1 :: * -> *) (ctx2 :: * -> *)
(sig :: (* -> *) -> * -> *) (m :: * -> *) (n :: * -> *) a.
(Functor ctx1, Functor ctx2, Algebra sig m) =>
Handler (Compose ctx1 ctx2) n m
-> sig n a -> ctx1 (ctx2 ()) -> m (ctx1 (ctx2 a))
thread (forall (m :: * -> *) a.
Applicative m =>
ChooseC Identity (ChooseC m a) -> m (ChooseC Identity a)
dst forall (n :: * -> *) (ctx1 :: * -> *) (m :: * -> *)
(ctx2 :: * -> *) (l :: * -> *).
(Functor n, Functor ctx1) =>
Handler ctx1 m n
-> Handler ctx2 l m -> Handler (Compose ctx1 ctx2) l n
~<~ Handler ctx n (ChooseC m)
hdl) sig n a
other (forall (f :: * -> *) a. Applicative f => a -> f a
pure ctx ()
ctx) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall a. Identity a -> a
run forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) b a.
(m b -> m b -> m b) -> (a -> m b) -> ChooseC m a -> m b
runChoose (coerce :: forall a b. Coercible a b => a -> b
coerce m b -> m b -> m b
fork) (coerce :: forall a b. Coercible a b => a -> b
coerce ctx a -> m b
leaf)
where
dst :: Applicative m => ChooseC Identity (ChooseC m a) -> m (ChooseC Identity a)
dst :: forall (m :: * -> *) a.
Applicative m =>
ChooseC Identity (ChooseC m a) -> m (ChooseC Identity a)
dst = forall a. Identity a -> a
run forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) b a.
(m b -> m b -> m b) -> (a -> m b) -> ChooseC m a -> m b
runChoose (forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 forall (sig :: (* -> *) -> * -> *) (m :: * -> *) a.
Has Choose sig m =>
m a -> m a -> m a
(<|>))) (forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) b a.
(m b -> m b -> m b) -> (a -> m b) -> ChooseC m a -> m b
runChoose (forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 forall (sig :: (* -> *) -> * -> *) (m :: * -> *) a.
Has Choose sig m =>
m a -> m a -> m a
(<|>)) (forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a. Applicative f => a -> f a
pure))
{-# INLINE alg #-}