{-# LANGUAGE GADTs, RankNTypes, TupleSections #-}
module Control.Selective.Rigid.Free (
Select (..), liftSelect,
getPure, getEffects, getNecessaryEffect, runSelect, foldSelect
) where
import Control.Monad.Trans.Except
import Control.Selective
import Data.Bifunctor
import Data.Functor
data Select f a where
Pure :: a -> Select f a
Select :: Select f (Either a b) -> f (a -> b) -> Select f b
instance Functor f => Functor (Select f) where
fmap :: (a -> b) -> Select f a -> Select f b
fmap a -> b
f (Pure a
a) = b -> Select f b
forall a (f :: * -> *). a -> Select f a
Pure (a -> b
f a
a)
fmap a -> b
f (Select Select f (Either a a)
x f (a -> a)
y) = Select f (Either a b) -> f (a -> b) -> Select f b
forall (f :: * -> *) a b.
Select f (Either a b) -> f (a -> b) -> Select f b
Select ((a -> b) -> Either a a -> Either a b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f (Either a a -> Either a b)
-> Select f (Either a a) -> Select f (Either a b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Select f (Either a a)
x) ((a -> b) -> (a -> a) -> a -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f ((a -> a) -> a -> b) -> f (a -> a) -> f (a -> b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f (a -> a)
y)
instance Functor f => Applicative (Select f) where
pure :: a -> Select f a
pure = a -> Select f a
forall a (f :: * -> *). a -> Select f a
Pure
<*> :: Select f (a -> b) -> Select f a -> Select f b
(<*>) = Select f (a -> b) -> Select f a -> Select f b
forall (f :: * -> *) a b. Selective f => f (a -> b) -> f a -> f b
apS
instance Functor f => Selective (Select f) where
select :: Select f (Either a b) -> Select f (a -> b) -> Select f b
select Select f (Either a b)
x (Pure a -> b
y) = (a -> b) -> (b -> b) -> Either a b -> b
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either a -> b
y b -> b
forall a. a -> a
id (Either a b -> b) -> Select f (Either a b) -> Select f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Select f (Either a b)
x
select Select f (Either a b)
x (Select Select f (Either a (a -> b))
y f (a -> a -> b)
z) = Select f (Either (a, a) b) -> f ((a, a) -> b) -> Select f b
forall (f :: * -> *) a b.
Select f (Either a b) -> f (a -> b) -> Select f b
Select (Select f (Either a (Either (a, a) b))
-> Select f (a -> Either (a, a) b) -> Select f (Either (a, a) b)
forall (f :: * -> *) a b.
Selective f =>
f (Either a b) -> f (a -> b) -> f b
select (Either a b -> Either a (Either (a, a) b)
forall (f :: * -> *) b a. Functor f => f b -> f (Either a b)
f (Either a b -> Either a (Either (a, a) b))
-> Select f (Either a b) -> Select f (Either a (Either (a, a) b))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Select f (Either a b)
x) (Either a (a -> b) -> a -> Either (a, a) b
forall (p :: * -> * -> *) t a d.
Bifunctor p =>
p t (a -> d) -> a -> p (t, a) d
g (Either a (a -> b) -> a -> Either (a, a) b)
-> Select f (Either a (a -> b)) -> Select f (a -> Either (a, a) b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Select f (Either a (a -> b))
y)) ((a -> a -> b) -> (a, a) -> b
forall a b c. (a -> b -> c) -> (a, b) -> c
h ((a -> a -> b) -> (a, a) -> b)
-> f (a -> a -> b) -> f ((a, a) -> b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f (a -> a -> b)
z)
where
f :: f b -> f (Either a b)
f f b
x = b -> Either a b
forall a b. b -> Either a b
Right (b -> Either a b) -> f b -> f (Either a b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f b
x
g :: p t (a -> d) -> a -> p (t, a) d
g p t (a -> d)
y = \a
a -> (t -> (t, a)) -> ((a -> d) -> d) -> p t (a -> d) -> p (t, a) d
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap (,a
a) ((a -> d) -> a -> d
forall a b. (a -> b) -> a -> b
$a
a) p t (a -> d)
y
h :: (a -> b -> c) -> (a, b) -> c
h a -> b -> c
z = (a -> b -> c) -> (a, b) -> c
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry a -> b -> c
z
liftSelect :: Functor f => f a -> Select f a
liftSelect :: f a -> Select f a
liftSelect f a
f = Select f (Either () a) -> f (() -> a) -> Select f a
forall (f :: * -> *) a b.
Select f (Either a b) -> f (a -> b) -> Select f b
Select (Either () a -> Select f (Either () a)
forall a (f :: * -> *). a -> Select f a
Pure (() -> Either () a
forall a b. a -> Either a b
Left ())) (a -> () -> a
forall a b. a -> b -> a
const (a -> () -> a) -> f a -> f (() -> a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f a
f)
runSelect :: Selective g => (forall x. f x -> g x) -> Select f a -> g a
runSelect :: (forall x. f x -> g x) -> Select f a -> g a
runSelect forall x. f x -> g x
_ (Pure a
a) = a -> g a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
a
runSelect forall x. f x -> g x
t (Select Select f (Either a a)
x f (a -> a)
y) = g (Either a a) -> g (a -> a) -> g a
forall (f :: * -> *) a b.
Selective f =>
f (Either a b) -> f (a -> b) -> f b
select ((forall x. f x -> g x) -> Select f (Either a a) -> g (Either a a)
forall (g :: * -> *) (f :: * -> *) a.
Selective g =>
(forall x. f x -> g x) -> Select f a -> g a
runSelect forall x. f x -> g x
t Select f (Either a a)
x) (f (a -> a) -> g (a -> a)
forall x. f x -> g x
t f (a -> a)
y)
foldSelect :: Monoid m => (forall x. f x -> m) -> Select f a -> m
foldSelect :: (forall x. f x -> m) -> Select f a -> m
foldSelect forall x. f x -> m
f = Over m a -> m
forall m a. Over m a -> m
getOver (Over m a -> m) -> (Select f a -> Over m a) -> Select f a -> m
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall x. f x -> Over m x) -> Select f a -> Over m a
forall (g :: * -> *) (f :: * -> *) a.
Selective g =>
(forall x. f x -> g x) -> Select f a -> g a
runSelect (m -> Over m x
forall m a. m -> Over m a
Over (m -> Over m x) -> (f x -> m) -> f x -> Over m x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f x -> m
forall x. f x -> m
f)
getPure :: Select f a -> Maybe a
getPure :: Select f a -> Maybe a
getPure = (forall x. f x -> Maybe x) -> Select f a -> Maybe a
forall (g :: * -> *) (f :: * -> *) a.
Selective g =>
(forall x. f x -> g x) -> Select f a -> g a
runSelect (Maybe x -> f x -> Maybe x
forall a b. a -> b -> a
const Maybe x
forall a. Maybe a
Nothing)
getEffects :: Functor f => Select f a -> [f ()]
getEffects :: Select f a -> [f ()]
getEffects = (forall x. f x -> [f ()]) -> Select f a -> [f ()]
forall m (f :: * -> *) a.
Monoid m =>
(forall x. f x -> m) -> Select f a -> m
foldSelect (f () -> [f ()]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (f () -> [f ()]) -> (f x -> f ()) -> f x -> [f ()]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f x -> f ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void)
getNecessaryEffect :: Functor f => Select f a -> Maybe (f ())
getNecessaryEffect :: Select f a -> Maybe (f ())
getNecessaryEffect = Either (f ()) a -> Maybe (f ())
forall a b. Either a b -> Maybe a
leftToMaybe (Either (f ()) a -> Maybe (f ()))
-> (Select f a -> Either (f ()) a) -> Select f a -> Maybe (f ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Except (f ()) a -> Either (f ()) a
forall e a. Except e a -> Either e a
runExcept (Except (f ()) a -> Either (f ()) a)
-> (Select f a -> Except (f ()) a) -> Select f a -> Either (f ()) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall x. f x -> ExceptT (f ()) Identity x)
-> Select f a -> Except (f ()) a
forall (g :: * -> *) (f :: * -> *) a.
Selective g =>
(forall x. f x -> g x) -> Select f a -> g a
runSelect (f () -> ExceptT (f ()) Identity x
forall (m :: * -> *) e a. Monad m => e -> ExceptT e m a
throwE (f () -> ExceptT (f ()) Identity x)
-> (f x -> f ()) -> f x -> ExceptT (f ()) Identity x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f x -> f ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void)
leftToMaybe :: Either a b -> Maybe a
leftToMaybe :: Either a b -> Maybe a
leftToMaybe (Left a
a) = a -> Maybe a
forall a. a -> Maybe a
Just a
a
leftToMaybe Either a b
_ = Maybe a
forall a. Maybe a
Nothing