{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
module Control.Variadic where

import Control.Monad.Morph (MFunctor(hoist), MMonad, MonadTrans)
import Control.Monad.Reader (ReaderT(ReaderT))
import Control.Variadic.Varargs (Varargs(Cons, Nil))
import Data.Functor (void)

-- | Same as 'Variadic' but captures the higher-kinded type parameter in the
-- return type. Useful so we can use 'Monad' and friends with 'Variadic'
-- functions.
newtype VariadicT args (m :: * -> *) a = VariadicT
  { VariadicT args m a -> Variadic args (m a)
unVariadicT :: Variadic args (m a)
  } deriving (a -> VariadicT args m b -> VariadicT args m a
(a -> b) -> VariadicT args m a -> VariadicT args m b
(forall a b. (a -> b) -> VariadicT args m a -> VariadicT args m b)
-> (forall a b. a -> VariadicT args m b -> VariadicT args m a)
-> Functor (VariadicT args m)
forall (args :: [*]) (m :: * -> *) a b.
Functor m =>
a -> VariadicT args m b -> VariadicT args m a
forall (args :: [*]) (m :: * -> *) a b.
Functor m =>
(a -> b) -> VariadicT args m a -> VariadicT args m b
forall a b. a -> VariadicT args m b -> VariadicT args m a
forall a b. (a -> b) -> VariadicT args m a -> VariadicT args m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> VariadicT args m b -> VariadicT args m a
$c<$ :: forall (args :: [*]) (m :: * -> *) a b.
Functor m =>
a -> VariadicT args m b -> VariadicT args m a
fmap :: (a -> b) -> VariadicT args m a -> VariadicT args m b
$cfmap :: forall (args :: [*]) (m :: * -> *) a b.
Functor m =>
(a -> b) -> VariadicT args m a -> VariadicT args m b
Functor, Functor (VariadicT args m)
a -> VariadicT args m a
Functor (VariadicT args m) =>
(forall a. a -> VariadicT args m a)
-> (forall a b.
    VariadicT args m (a -> b)
    -> VariadicT args m a -> VariadicT args m b)
-> (forall a b c.
    (a -> b -> c)
    -> VariadicT args m a -> VariadicT args m b -> VariadicT args m c)
-> (forall a b.
    VariadicT args m a -> VariadicT args m b -> VariadicT args m b)
-> (forall a b.
    VariadicT args m a -> VariadicT args m b -> VariadicT args m a)
-> Applicative (VariadicT args m)
VariadicT args m a -> VariadicT args m b -> VariadicT args m b
VariadicT args m a -> VariadicT args m b -> VariadicT args m a
VariadicT args m (a -> b)
-> VariadicT args m a -> VariadicT args m b
(a -> b -> c)
-> VariadicT args m a -> VariadicT args m b -> VariadicT args m c
forall (args :: [*]) (m :: * -> *).
Applicative m =>
Functor (VariadicT args m)
forall (args :: [*]) (m :: * -> *) a.
Applicative m =>
a -> VariadicT args m a
forall (args :: [*]) (m :: * -> *) a b.
Applicative m =>
VariadicT args m a -> VariadicT args m b -> VariadicT args m a
forall (args :: [*]) (m :: * -> *) a b.
Applicative m =>
VariadicT args m a -> VariadicT args m b -> VariadicT args m b
forall (args :: [*]) (m :: * -> *) a b.
Applicative m =>
VariadicT args m (a -> b)
-> VariadicT args m a -> VariadicT args m b
forall (args :: [*]) (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> VariadicT args m a -> VariadicT args m b -> VariadicT args m c
forall a. a -> VariadicT args m a
forall a b.
VariadicT args m a -> VariadicT args m b -> VariadicT args m a
forall a b.
VariadicT args m a -> VariadicT args m b -> VariadicT args m b
forall a b.
VariadicT args m (a -> b)
-> VariadicT args m a -> VariadicT args m b
forall a b c.
(a -> b -> c)
-> VariadicT args m a -> VariadicT args m b -> VariadicT args m c
forall (f :: * -> *).
Functor f =>
(forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: VariadicT args m a -> VariadicT args m b -> VariadicT args m a
$c<* :: forall (args :: [*]) (m :: * -> *) a b.
Applicative m =>
VariadicT args m a -> VariadicT args m b -> VariadicT args m a
*> :: VariadicT args m a -> VariadicT args m b -> VariadicT args m b
$c*> :: forall (args :: [*]) (m :: * -> *) a b.
Applicative m =>
VariadicT args m a -> VariadicT args m b -> VariadicT args m b
liftA2 :: (a -> b -> c)
-> VariadicT args m a -> VariadicT args m b -> VariadicT args m c
$cliftA2 :: forall (args :: [*]) (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> VariadicT args m a -> VariadicT args m b -> VariadicT args m c
<*> :: VariadicT args m (a -> b)
-> VariadicT args m a -> VariadicT args m b
$c<*> :: forall (args :: [*]) (m :: * -> *) a b.
Applicative m =>
VariadicT args m (a -> b)
-> VariadicT args m a -> VariadicT args m b
pure :: a -> VariadicT args m a
$cpure :: forall (args :: [*]) (m :: * -> *) a.
Applicative m =>
a -> VariadicT args m a
$cp1Applicative :: forall (args :: [*]) (m :: * -> *).
Applicative m =>
Functor (VariadicT args m)
Applicative, Applicative (VariadicT args m)
a -> VariadicT args m a
Applicative (VariadicT args m) =>
(forall a b.
 VariadicT args m a
 -> (a -> VariadicT args m b) -> VariadicT args m b)
-> (forall a b.
    VariadicT args m a -> VariadicT args m b -> VariadicT args m b)
-> (forall a. a -> VariadicT args m a)
-> Monad (VariadicT args m)
VariadicT args m a
-> (a -> VariadicT args m b) -> VariadicT args m b
VariadicT args m a -> VariadicT args m b -> VariadicT args m b
forall (args :: [*]) (m :: * -> *).
Monad m =>
Applicative (VariadicT args m)
forall (args :: [*]) (m :: * -> *) a.
Monad m =>
a -> VariadicT args m a
forall (args :: [*]) (m :: * -> *) a b.
Monad m =>
VariadicT args m a -> VariadicT args m b -> VariadicT args m b
forall (args :: [*]) (m :: * -> *) a b.
Monad m =>
VariadicT args m a
-> (a -> VariadicT args m b) -> VariadicT args m b
forall a. a -> VariadicT args m a
forall a b.
VariadicT args m a -> VariadicT args m b -> VariadicT args m b
forall a b.
VariadicT args m a
-> (a -> VariadicT args m b) -> VariadicT args m b
forall (m :: * -> *).
Applicative m =>
(forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: a -> VariadicT args m a
$creturn :: forall (args :: [*]) (m :: * -> *) a.
Monad m =>
a -> VariadicT args m a
>> :: VariadicT args m a -> VariadicT args m b -> VariadicT args m b
$c>> :: forall (args :: [*]) (m :: * -> *) a b.
Monad m =>
VariadicT args m a -> VariadicT args m b -> VariadicT args m b
>>= :: VariadicT args m a
-> (a -> VariadicT args m b) -> VariadicT args m b
$c>>= :: forall (args :: [*]) (m :: * -> *) a b.
Monad m =>
VariadicT args m a
-> (a -> VariadicT args m b) -> VariadicT args m b
$cp1Monad :: forall (args :: [*]) (m :: * -> *).
Monad m =>
Applicative (VariadicT args m)
Monad) via ReaderT (Varargs args) m
    deriving ((forall a. m a -> n a) -> VariadicT args m b -> VariadicT args n b
(forall (m :: * -> *) (n :: * -> *) b.
 Monad m =>
 (forall a. m a -> n a) -> VariadicT args m b -> VariadicT args n b)
-> MFunctor (VariadicT args)
forall (args :: [*]) (m :: * -> *) (n :: * -> *) b.
Monad m =>
(forall a. m a -> n a) -> VariadicT args m b -> VariadicT args n b
forall k (t :: (* -> *) -> k -> *).
(forall (m :: * -> *) (n :: * -> *) (b :: k).
 Monad m =>
 (forall a. m a -> n a) -> t m b -> t n b)
-> MFunctor t
forall (m :: * -> *) (n :: * -> *) b.
Monad m =>
(forall a. m a -> n a) -> VariadicT args m b -> VariadicT args n b
hoist :: (forall a. m a -> n a) -> VariadicT args m b -> VariadicT args n b
$choist :: forall (args :: [*]) (m :: * -> *) (n :: * -> *) b.
Monad m =>
(forall a. m a -> n a) -> VariadicT args m b -> VariadicT args n b
MFunctor, MFunctor (VariadicT args)
MonadTrans (VariadicT args)
(MFunctor (VariadicT args), MonadTrans (VariadicT args)) =>
(forall (n :: * -> *) (m :: * -> *) b.
 Monad n =>
 (forall a. m a -> VariadicT args n a)
 -> VariadicT args m b -> VariadicT args n b)
-> MMonad (VariadicT args)
(forall a. m a -> VariadicT args n a)
-> VariadicT args m b -> VariadicT args n b
forall (args :: [*]). MFunctor (VariadicT args)
forall (args :: [*]). MonadTrans (VariadicT args)
forall (args :: [*]) (n :: * -> *) (m :: * -> *) b.
Monad n =>
(forall a. m a -> VariadicT args n a)
-> VariadicT args m b -> VariadicT args n b
forall (n :: * -> *) (m :: * -> *) b.
Monad n =>
(forall a. m a -> VariadicT args n a)
-> VariadicT args m b -> VariadicT args n b
forall (t :: (* -> *) -> * -> *).
(MFunctor t, MonadTrans t) =>
(forall (n :: * -> *) (m :: * -> *) b.
 Monad n =>
 (forall a. m a -> t n a) -> t m b -> t n b)
-> MMonad t
embed :: (forall a. m a -> VariadicT args n a)
-> VariadicT args m b -> VariadicT args n b
$cembed :: forall (args :: [*]) (n :: * -> *) (m :: * -> *) b.
Monad n =>
(forall a. m a -> VariadicT args n a)
-> VariadicT args m b -> VariadicT args n b
$cp2MMonad :: forall (args :: [*]). MonadTrans (VariadicT args)
$cp1MMonad :: forall (args :: [*]). MFunctor (VariadicT args)
MMonad, m a -> VariadicT args m a
(forall (m :: * -> *) a. Monad m => m a -> VariadicT args m a)
-> MonadTrans (VariadicT args)
forall (args :: [*]) (m :: * -> *) a.
Monad m =>
m a -> VariadicT args m a
forall (m :: * -> *) a. Monad m => m a -> VariadicT args m a
forall (t :: (* -> *) -> * -> *).
(forall (m :: * -> *) a. Monad m => m a -> t m a) -> MonadTrans t
lift :: m a -> VariadicT args m a
$clift :: forall (args :: [*]) (m :: * -> *) a.
Monad m =>
m a -> VariadicT args m a
MonadTrans) via ReaderT (Varargs args)

-- | Converts a function to a 'VariadicT'. Analogous to 'toVariadic'.
toVariadicT
  :: ( ToVariadic x
     , args ~ ToVariadicArgs x
     , m r ~ ToVariadicReturn x
     )
  => x -> VariadicT args m r
toVariadicT :: x -> VariadicT args m r
toVariadicT = Variadic args (m r) -> VariadicT args m r
forall (args :: [*]) (m :: * -> *) a.
Variadic args (m a) -> VariadicT args m a
VariadicT (Variadic args (m r) -> VariadicT args m r)
-> (x -> Variadic args (m r)) -> x -> VariadicT args m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. x -> Variadic args (m r)
forall x.
ToVariadic x =>
x -> Variadic (ToVariadicArgs x) (ToVariadicReturn x)
toVariadic

-- | Converts a 'VariadicT' to a normal function. Analogous to 'fromVariadic'.
fromVariadicT
  :: ( FromVariadic args (m r)
     )
  => VariadicT args m r -> FromVariadicSignature args (m r)
fromVariadicT :: VariadicT args m r -> FromVariadicSignature args (m r)
fromVariadicT = Variadic args (m r) -> FromVariadicSignature args (m r)
forall (args :: [*]) r.
FromVariadic args r =>
Variadic args r -> FromVariadicSignature args r
fromVariadic (Variadic args (m r) -> FromVariadicSignature args (m r))
-> (VariadicT args m r -> Variadic args (m r))
-> VariadicT args m r
-> FromVariadicSignature args (m r)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VariadicT args m r -> Variadic args (m r)
forall (args :: [*]) (m :: * -> *) a.
VariadicT args m a -> Variadic args (m a)
unVariadicT

-- | A function whose argument list is collapsed into 'Varargs'
-- and shows its return type.
newtype Variadic args a = Variadic
  { Variadic args a -> Varargs args -> a
runVariadic :: Varargs args -> a
  }

-- | Resolves the argument list for a function of arbitrary arity.
type family ToVariadicArgs x :: [*] where
  ToVariadicArgs (i -> o) = i ': ToVariadicArgs o
  ToVariadicArgs a = '[]

-- | Resolves the return type for a function of arbitrary arity.
type family ToVariadicReturn x :: * where
  ToVariadicReturn (i -> o) = ToVariadicReturn o
  ToVariadicReturn a = a

-- | Converts a function of arbitrary arity to 'Variadic'.
class ToVariadic x where
  toVariadic :: x -> Variadic (ToVariadicArgs x) (ToVariadicReturn x)

instance {-# OVERLAPPING #-}
  ( ToVariadicArgs a ~ '[]
  , ToVariadicReturn a ~ a
  ) => ToVariadic a where
  toVariadic :: a -> Variadic (ToVariadicArgs a) (ToVariadicReturn a)
toVariadic a :: a
a = (Varargs '[] -> a) -> Variadic '[] a
forall (args :: [*]) a. (Varargs args -> a) -> Variadic args a
Variadic \_ -> a
a

instance {-# OVERLAPS #-}
  ( ToVariadic o
  , ToVariadicArgs (i -> o) ~ (i ': args)
  , ToVariadicArgs o ~ args
  , ToVariadicReturn (i -> o) ~ ToVariadicReturn o
  ) => ToVariadic (i -> o)
  where
  toVariadic :: (i -> o)
-> Variadic (ToVariadicArgs (i -> o)) (ToVariadicReturn (i -> o))
toVariadic f :: i -> o
f =
    (Varargs (i : args) -> ToVariadicReturn o)
-> Variadic (i : args) (ToVariadicReturn o)
forall (args :: [*]) a. (Varargs args -> a) -> Variadic args a
Variadic \(arg `Cons` args) ->
      Variadic args (ToVariadicReturn o)
-> Varargs args -> ToVariadicReturn o
forall (args :: [*]) a. Variadic args a -> Varargs args -> a
runVariadic (o -> Variadic (ToVariadicArgs o) (ToVariadicReturn o)
forall x.
ToVariadic x =>
x -> Variadic (ToVariadicArgs x) (ToVariadicReturn x)
toVariadic (i -> o
f i
arg)) Varargs args
args

-- | Builds a function signature given the @args@ and return type @r@.
type family FromVariadicSignature (args :: [*]) (r :: *) :: * where
  FromVariadicSignature '[] r = r
  FromVariadicSignature (arg ': args) r = arg -> FromVariadicSignature args r

-- | Converts a 'Variadic' to a normal function.
class FromVariadic args r where
  fromVariadic :: Variadic args r -> FromVariadicSignature args r

instance FromVariadic '[] a where
  fromVariadic :: Variadic '[] a -> FromVariadicSignature '[] a
fromVariadic v :: Variadic '[] a
v = Variadic '[] a -> Varargs '[] -> a
forall (args :: [*]) a. Variadic args a -> Varargs args -> a
runVariadic Variadic '[] a
v Varargs '[]
Nil

instance (FromVariadic args a) => FromVariadic (arg ': args) a where
  fromVariadic :: Variadic (arg : args) a -> FromVariadicSignature (arg : args) a
fromVariadic v :: Variadic (arg : args) a
v arg :: arg
arg =
    Variadic args a -> FromVariadicSignature args a
forall (args :: [*]) r.
FromVariadic args r =>
Variadic args r -> FromVariadicSignature args r
fromVariadic (Variadic args a -> FromVariadicSignature args a)
-> Variadic args a -> FromVariadicSignature args a
forall a b. (a -> b) -> a -> b
$ (Varargs args -> a) -> Variadic args a
forall (args :: [*]) a. (Varargs args -> a) -> Variadic args a
Variadic \args :: Varargs args
args ->
      Variadic (arg : args) a -> Varargs (arg : args) -> a
forall (args :: [*]) a. Variadic args a -> Varargs args -> a
runVariadic Variadic (arg : args) a
v (arg
arg arg -> Varargs args -> Varargs (arg : args)
forall x (xs :: [*]). x -> Varargs xs -> Varargs (x : xs)
`Cons` Varargs args
args)

-- | Convenience constraint enabling variadic.
--
-- @x@ is the Haskell function type,
-- @args@ is a type-level list of arguments,
-- @r@ is the return type.
--
-- Usually you'll want to use these type arguments polymorphically, e.g. -
--
-- > (...*>)
-- >   :: ( Applicative m
-- >      , IsVariadic va args (m a)
-- >      , IsVariadic vb args (m b)
-- >      )
-- >   => va -> vb -> vb
-- > va ...*> vb = fromVariadicT $ toVariadicT va *> toVariadicT vb
type IsVariadic x args r =
  ( ToVariadic x
  , args ~ ToVariadicArgs x
  , r ~ ToVariadicReturn x
  , x ~ FromVariadicSignature args r
  , FromVariadic args r
  )

-- | Analogous to 'fmap' for 'VariadicT' but works on vanilla functions.
vmap
  :: ( Functor f
     , IsVariadic va args (f a)
     , IsVariadic vb args (f b)
     )
  => (a -> b) -> va -> vb
vmap :: (a -> b) -> va -> vb
vmap f :: a -> b
f va :: va
va = VariadicT args f b -> vb
forall (args :: [*]) (m :: * -> *) r.
FromVariadic args (m r) =>
VariadicT args m r -> FromVariadicSignature args (m r)
fromVariadicT (VariadicT args f b -> vb) -> VariadicT args f b -> vb
forall a b. (a -> b) -> a -> b
$ (a -> b) -> VariadicT args f a -> VariadicT args f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f (VariadicT args f a -> VariadicT args f b)
-> VariadicT args f a -> VariadicT args f b
forall a b. (a -> b) -> a -> b
$ va -> VariadicT args f a
forall x (args :: [*]) (m :: * -> *) r.
(ToVariadic x, args ~ ToVariadicArgs x,
 m r ~ ToVariadicReturn x) =>
x -> VariadicT args m r
toVariadicT va
va

-- | Analogous to 'fmap' for 'VariadicT' but works on vanilla functions.
(<$>...)
  :: ( Functor f
     , IsVariadic va args (f a)
     , IsVariadic vb args (f b)
     )
  => (a -> b) -> va -> vb
<$>... :: (a -> b) -> va -> vb
(<$>...) = (a -> b) -> va -> vb
forall (f :: * -> *) va (args :: [*]) a vb b.
(Functor f, IsVariadic va args (f a), IsVariadic vb args (f b)) =>
(a -> b) -> va -> vb
vmap

-- | Analogous to 'void' for 'VariadicT' but works on vanilla functions.
vvoid
  :: ( Functor f
     , IsVariadic va args (f a)
     , IsVariadic vu args (f ())
     )
  => va -> vu
vvoid :: va -> vu
vvoid va :: va
va = VariadicT args f () -> vu
forall (args :: [*]) (m :: * -> *) r.
FromVariadic args (m r) =>
VariadicT args m r -> FromVariadicSignature args (m r)
fromVariadicT (VariadicT args f () -> vu) -> VariadicT args f () -> vu
forall a b. (a -> b) -> a -> b
$ VariadicT args f a -> VariadicT args f ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (VariadicT args f a -> VariadicT args f ())
-> VariadicT args f a -> VariadicT args f ()
forall a b. (a -> b) -> a -> b
$ va -> VariadicT args f a
forall x (args :: [*]) (m :: * -> *) r.
(ToVariadic x, args ~ ToVariadicArgs x,
 m r ~ ToVariadicReturn x) =>
x -> VariadicT args m r
toVariadicT va
va

-- | Analogous to '*>' for 'VariadicT' but works on vanilla functions.
(...*>)
  :: ( Applicative m
     , IsVariadic va args (m a)
     , IsVariadic vb args (m b)
     )
  => va -> vb -> vb
va :: va
va ...*> :: va -> vb -> vb
...*> vb :: vb
vb = VariadicT args m b -> vb
forall (args :: [*]) (m :: * -> *) r.
FromVariadic args (m r) =>
VariadicT args m r -> FromVariadicSignature args (m r)
fromVariadicT (VariadicT args m b -> vb) -> VariadicT args m b -> vb
forall a b. (a -> b) -> a -> b
$ va -> VariadicT args m a
forall x (args :: [*]) (m :: * -> *) r.
(ToVariadic x, args ~ ToVariadicArgs x,
 m r ~ ToVariadicReturn x) =>
x -> VariadicT args m r
toVariadicT va
va VariadicT args m a -> VariadicT args m b -> VariadicT args m b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> vb -> VariadicT args m b
forall x (args :: [*]) (m :: * -> *) r.
(ToVariadic x, args ~ ToVariadicArgs x,
 m r ~ ToVariadicReturn x) =>
x -> VariadicT args m r
toVariadicT vb
vb

-- | Analogous to '<*' for 'VariadicT' but works on vanilla functions.
(<*...)
  :: ( Applicative m
     , IsVariadic va args (m a)
     , IsVariadic vb args (m b)
     )
  => va -> vb -> va
va :: va
va <*... :: va -> vb -> va
<*... vb :: vb
vb = VariadicT args m a -> va
forall (args :: [*]) (m :: * -> *) r.
FromVariadic args (m r) =>
VariadicT args m r -> FromVariadicSignature args (m r)
fromVariadicT (VariadicT args m a -> va) -> VariadicT args m a -> va
forall a b. (a -> b) -> a -> b
$ va -> VariadicT args m a
forall x (args :: [*]) (m :: * -> *) r.
(ToVariadic x, args ~ ToVariadicArgs x,
 m r ~ ToVariadicReturn x) =>
x -> VariadicT args m r
toVariadicT va
va VariadicT args m a -> VariadicT args m b -> VariadicT args m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* vb -> VariadicT args m b
forall x (args :: [*]) (m :: * -> *) r.
(ToVariadic x, args ~ ToVariadicArgs x,
 m r ~ ToVariadicReturn x) =>
x -> VariadicT args m r
toVariadicT vb
vb

-- | Analogous to '>>=' for 'VariadicT' but works on vanilla functions.
(...>>=)
  :: ( Monad m
     , IsVariadic va args (m a)
     , IsVariadic vb args (m b)
     )
  => va -> (a -> vb) -> vb
va :: va
va ...>>= :: va -> (a -> vb) -> vb
...>>= f :: a -> vb
f = VariadicT args m b -> vb
forall (args :: [*]) (m :: * -> *) r.
FromVariadic args (m r) =>
VariadicT args m r -> FromVariadicSignature args (m r)
fromVariadicT (VariadicT args m b -> vb) -> VariadicT args m b -> vb
forall a b. (a -> b) -> a -> b
$ va -> VariadicT args m a
forall x (args :: [*]) (m :: * -> *) r.
(ToVariadic x, args ~ ToVariadicArgs x,
 m r ~ ToVariadicReturn x) =>
x -> VariadicT args m r
toVariadicT va
va VariadicT args m a
-> (a -> VariadicT args m b) -> VariadicT args m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \a :: a
a -> vb -> VariadicT args m b
forall x (args :: [*]) (m :: * -> *) r.
(ToVariadic x, args ~ ToVariadicArgs x,
 m r ~ ToVariadicReturn x) =>
x -> VariadicT args m r
toVariadicT (a -> vb
f a
a)

-- | Analogous to '=<<' for 'VariadicT' but works on vanilla functions.
(=<<...)
  :: ( Monad m
     , IsVariadic va args (m a)
     , IsVariadic vb args (m b)
     )
  => (a -> vb) -> va -> vb
=<<... :: (a -> vb) -> va -> vb
(=<<...) = (va -> (a -> vb) -> vb) -> (a -> vb) -> va -> vb
forall a b c. (a -> b -> c) -> b -> a -> c
flip va -> (a -> vb) -> vb
forall (m :: * -> *) va (args :: [*]) a vb b.
(Monad m, IsVariadic va args (m a), IsVariadic vb args (m b)) =>
va -> (a -> vb) -> vb
(...>>=)

-- | Analogous to 'hoist' for 'VariadicT' but works on vanilla functions.
vhoist
  :: ( Monad f
     , IsVariadic vf args (f a)
     , IsVariadic vg args (g a)
     )
  => (forall x. f x -> g x) -> vf -> vg
vhoist :: (forall x. f x -> g x) -> vf -> vg
vhoist f :: forall x. f x -> g x
f = VariadicT args g a -> vg
forall (args :: [*]) (m :: * -> *) r.
FromVariadic args (m r) =>
VariadicT args m r -> FromVariadicSignature args (m r)
fromVariadicT (VariadicT args g a -> vg)
-> (vf -> VariadicT args g a) -> vf -> vg
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall x. f x -> g x) -> VariadicT args f a -> VariadicT args g a
forall k (t :: (* -> *) -> k -> *) (m :: * -> *) (n :: * -> *)
       (b :: k).
(MFunctor t, Monad m) =>
(forall a. m a -> n a) -> t m b -> t n b
hoist forall x. f x -> g x
f (VariadicT args f a -> VariadicT args g a)
-> (vf -> VariadicT args f a) -> vf -> VariadicT args g a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. vf -> VariadicT args f a
forall x (args :: [*]) (m :: * -> *) r.
(ToVariadic x, args ~ ToVariadicArgs x,
 m r ~ ToVariadicReturn x) =>
x -> VariadicT args m r
toVariadicT