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