{-# LANGUAGE FunctionalDependencies, TypeOperators #-}
module Control.Dual.Class where
import Control.Applicative ( ZipList(..) )
import Control.Concurrent.Async ( Concurrently(..) )
import Control.Natural ( (:~>)(..)
, (#)
)
import Data.Bitraversable ( Bitraversable
, bitraverse
)
import Data.Functor ( void )
import Data.Validation ( Validation
, toEither
, fromEither
)
class (Monad m, Applicative f) => Dual f m | m -> f, f -> m where
parallel :: m :~> f
sequential :: f :~> m
parMap2 :: m a0 -> m a1 -> (a0 -> a1 -> a) -> m a
parMap2 ma0 :: m a0
ma0 ma1 :: m a1
ma1 f :: a0 -> a1 -> a
f = (f :~> m) -> forall a. f a -> m a
forall k (f :: k -> *) (g :: k -> *) t.
Transformation f g t =>
t -> forall (a :: k). f a -> g a
(#) f :~> m
forall (f :: * -> *) (m :: * -> *). Dual f m => f :~> m
sequential (f a -> m a) -> f a -> m a
forall a b. (a -> b) -> a -> b
$ a0 -> a1 -> a
f
(a0 -> a1 -> a) -> f a0 -> f (a1 -> a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (m :~> f) -> m a0 -> f a0
forall k (f :: k -> *) (g :: k -> *) t.
Transformation f g t =>
t -> forall (a :: k). f a -> g a
(#) m :~> f
forall (f :: * -> *) (m :: * -> *). Dual f m => m :~> f
parallel m a0
ma0
f (a1 -> a) -> f a1 -> f a
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (m :~> f) -> m a1 -> f a1
forall k (f :: k -> *) (g :: k -> *) t.
Transformation f g t =>
t -> forall (a :: k). f a -> g a
(#) m :~> f
forall (f :: * -> *) (m :: * -> *). Dual f m => m :~> f
parallel m a1
ma1
parMap3 :: m a0 -> m a1 -> m a2 -> (a0 -> a1 -> a2 -> a) -> m a
parMap3 ma0 :: m a0
ma0 ma1 :: m a1
ma1 ma2 :: m a2
ma2 f :: a0 -> a1 -> a2 -> a
f = (f :~> m) -> forall a. f a -> m a
forall k (f :: k -> *) (g :: k -> *) t.
Transformation f g t =>
t -> forall (a :: k). f a -> g a
(#) f :~> m
forall (f :: * -> *) (m :: * -> *). Dual f m => f :~> m
sequential (f a -> m a) -> f a -> m a
forall a b. (a -> b) -> a -> b
$ a0 -> a1 -> a2 -> a
f
(a0 -> a1 -> a2 -> a) -> f a0 -> f (a1 -> a2 -> a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (m :~> f) -> m a0 -> f a0
forall k (f :: k -> *) (g :: k -> *) t.
Transformation f g t =>
t -> forall (a :: k). f a -> g a
(#) m :~> f
forall (f :: * -> *) (m :: * -> *). Dual f m => m :~> f
parallel m a0
ma0
f (a1 -> a2 -> a) -> f a1 -> f (a2 -> a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (m :~> f) -> m a1 -> f a1
forall k (f :: k -> *) (g :: k -> *) t.
Transformation f g t =>
t -> forall (a :: k). f a -> g a
(#) m :~> f
forall (f :: * -> *) (m :: * -> *). Dual f m => m :~> f
parallel m a1
ma1
f (a2 -> a) -> f a2 -> f a
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (m :~> f) -> m a2 -> f a2
forall k (f :: k -> *) (g :: k -> *) t.
Transformation f g t =>
t -> forall (a :: k). f a -> g a
(#) m :~> f
forall (f :: * -> *) (m :: * -> *). Dual f m => m :~> f
parallel m a2
ma2
parMap4 :: m a0 -> m a1 -> m a2 -> m a3 -> (a0 -> a1 -> a2 -> a3 -> a) -> m a
parMap4 ma0 :: m a0
ma0 ma1 :: m a1
ma1 ma2 :: m a2
ma2 ma3 :: m a3
ma3 f :: a0 -> a1 -> a2 -> a3 -> a
f = (f :~> m) -> forall a. f a -> m a
forall k (f :: k -> *) (g :: k -> *) t.
Transformation f g t =>
t -> forall (a :: k). f a -> g a
(#) f :~> m
forall (f :: * -> *) (m :: * -> *). Dual f m => f :~> m
sequential (f a -> m a) -> f a -> m a
forall a b. (a -> b) -> a -> b
$ a0 -> a1 -> a2 -> a3 -> a
f
(a0 -> a1 -> a2 -> a3 -> a) -> f a0 -> f (a1 -> a2 -> a3 -> a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (m :~> f) -> m a0 -> f a0
forall k (f :: k -> *) (g :: k -> *) t.
Transformation f g t =>
t -> forall (a :: k). f a -> g a
(#) m :~> f
forall (f :: * -> *) (m :: * -> *). Dual f m => m :~> f
parallel m a0
ma0
f (a1 -> a2 -> a3 -> a) -> f a1 -> f (a2 -> a3 -> a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (m :~> f) -> m a1 -> f a1
forall k (f :: k -> *) (g :: k -> *) t.
Transformation f g t =>
t -> forall (a :: k). f a -> g a
(#) m :~> f
forall (f :: * -> *) (m :: * -> *). Dual f m => m :~> f
parallel m a1
ma1
f (a2 -> a3 -> a) -> f a2 -> f (a3 -> a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (m :~> f) -> m a2 -> f a2
forall k (f :: k -> *) (g :: k -> *) t.
Transformation f g t =>
t -> forall (a :: k). f a -> g a
(#) m :~> f
forall (f :: * -> *) (m :: * -> *). Dual f m => m :~> f
parallel m a2
ma2
f (a3 -> a) -> f a3 -> f a
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (m :~> f) -> m a3 -> f a3
forall k (f :: k -> *) (g :: k -> *) t.
Transformation f g t =>
t -> forall (a :: k). f a -> g a
(#) m :~> f
forall (f :: * -> *) (m :: * -> *). Dual f m => m :~> f
parallel m a3
ma3
parMap5 :: m a0 -> m a1 -> m a2 -> m a3 -> m a4 -> (a0 -> a1 -> a2 -> a3 -> a4 -> a) -> m a
parMap5 ma0 :: m a0
ma0 ma1 :: m a1
ma1 ma2 :: m a2
ma2 ma3 :: m a3
ma3 ma4 :: m a4
ma4 f :: a0 -> a1 -> a2 -> a3 -> a4 -> a
f = (f :~> m) -> forall a. f a -> m a
forall k (f :: k -> *) (g :: k -> *) t.
Transformation f g t =>
t -> forall (a :: k). f a -> g a
(#) f :~> m
forall (f :: * -> *) (m :: * -> *). Dual f m => f :~> m
sequential (f a -> m a) -> f a -> m a
forall a b. (a -> b) -> a -> b
$ a0 -> a1 -> a2 -> a3 -> a4 -> a
f
(a0 -> a1 -> a2 -> a3 -> a4 -> a)
-> f a0 -> f (a1 -> a2 -> a3 -> a4 -> a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (m :~> f) -> m a0 -> f a0
forall k (f :: k -> *) (g :: k -> *) t.
Transformation f g t =>
t -> forall (a :: k). f a -> g a
(#) m :~> f
forall (f :: * -> *) (m :: * -> *). Dual f m => m :~> f
parallel m a0
ma0
f (a1 -> a2 -> a3 -> a4 -> a) -> f a1 -> f (a2 -> a3 -> a4 -> a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (m :~> f) -> m a1 -> f a1
forall k (f :: k -> *) (g :: k -> *) t.
Transformation f g t =>
t -> forall (a :: k). f a -> g a
(#) m :~> f
forall (f :: * -> *) (m :: * -> *). Dual f m => m :~> f
parallel m a1
ma1
f (a2 -> a3 -> a4 -> a) -> f a2 -> f (a3 -> a4 -> a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (m :~> f) -> m a2 -> f a2
forall k (f :: k -> *) (g :: k -> *) t.
Transformation f g t =>
t -> forall (a :: k). f a -> g a
(#) m :~> f
forall (f :: * -> *) (m :: * -> *). Dual f m => m :~> f
parallel m a2
ma2
f (a3 -> a4 -> a) -> f a3 -> f (a4 -> a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (m :~> f) -> m a3 -> f a3
forall k (f :: k -> *) (g :: k -> *) t.
Transformation f g t =>
t -> forall (a :: k). f a -> g a
(#) m :~> f
forall (f :: * -> *) (m :: * -> *). Dual f m => m :~> f
parallel m a3
ma3
f (a4 -> a) -> f a4 -> f a
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (m :~> f) -> m a4 -> f a4
forall k (f :: k -> *) (g :: k -> *) t.
Transformation f g t =>
t -> forall (a :: k). f a -> g a
(#) m :~> f
forall (f :: * -> *) (m :: * -> *). Dual f m => m :~> f
parallel m a4
ma4
parMap6 :: m a0 -> m a1 -> m a2 -> m a3 -> m a4 -> m a5 -> (a0 -> a1 -> a2 -> a3 -> a4 -> a5 -> a) -> m a
parMap6 ma0 :: m a0
ma0 ma1 :: m a1
ma1 ma2 :: m a2
ma2 ma3 :: m a3
ma3 ma4 :: m a4
ma4 ma5 :: m a5
ma5 f :: a0 -> a1 -> a2 -> a3 -> a4 -> a5 -> a
f = (f :~> m) -> forall a. f a -> m a
forall k (f :: k -> *) (g :: k -> *) t.
Transformation f g t =>
t -> forall (a :: k). f a -> g a
(#) f :~> m
forall (f :: * -> *) (m :: * -> *). Dual f m => f :~> m
sequential (f a -> m a) -> f a -> m a
forall a b. (a -> b) -> a -> b
$ a0 -> a1 -> a2 -> a3 -> a4 -> a5 -> a
f
(a0 -> a1 -> a2 -> a3 -> a4 -> a5 -> a)
-> f a0 -> f (a1 -> a2 -> a3 -> a4 -> a5 -> a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (m :~> f) -> m a0 -> f a0
forall k (f :: k -> *) (g :: k -> *) t.
Transformation f g t =>
t -> forall (a :: k). f a -> g a
(#) m :~> f
forall (f :: * -> *) (m :: * -> *). Dual f m => m :~> f
parallel m a0
ma0
f (a1 -> a2 -> a3 -> a4 -> a5 -> a)
-> f a1 -> f (a2 -> a3 -> a4 -> a5 -> a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (m :~> f) -> m a1 -> f a1
forall k (f :: k -> *) (g :: k -> *) t.
Transformation f g t =>
t -> forall (a :: k). f a -> g a
(#) m :~> f
forall (f :: * -> *) (m :: * -> *). Dual f m => m :~> f
parallel m a1
ma1
f (a2 -> a3 -> a4 -> a5 -> a) -> f a2 -> f (a3 -> a4 -> a5 -> a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (m :~> f) -> m a2 -> f a2
forall k (f :: k -> *) (g :: k -> *) t.
Transformation f g t =>
t -> forall (a :: k). f a -> g a
(#) m :~> f
forall (f :: * -> *) (m :: * -> *). Dual f m => m :~> f
parallel m a2
ma2
f (a3 -> a4 -> a5 -> a) -> f a3 -> f (a4 -> a5 -> a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (m :~> f) -> m a3 -> f a3
forall k (f :: k -> *) (g :: k -> *) t.
Transformation f g t =>
t -> forall (a :: k). f a -> g a
(#) m :~> f
forall (f :: * -> *) (m :: * -> *). Dual f m => m :~> f
parallel m a3
ma3
f (a4 -> a5 -> a) -> f a4 -> f (a5 -> a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (m :~> f) -> m a4 -> f a4
forall k (f :: k -> *) (g :: k -> *) t.
Transformation f g t =>
t -> forall (a :: k). f a -> g a
(#) m :~> f
forall (f :: * -> *) (m :: * -> *). Dual f m => m :~> f
parallel m a4
ma4
f (a5 -> a) -> f a5 -> f a
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (m :~> f) -> m a5 -> f a5
forall k (f :: k -> *) (g :: k -> *) t.
Transformation f g t =>
t -> forall (a :: k). f a -> g a
(#) m :~> f
forall (f :: * -> *) (m :: * -> *). Dual f m => m :~> f
parallel m a5
ma5
parTraverse :: Traversable t => (a -> m b) -> t a -> m (t b)
parTraverse f :: a -> m b
f ta :: t a
ta =
let g :: a -> g b
g a :: a
a = (m :~> g) -> m b -> g b
forall k (f :: k -> *) (g :: k -> *) t.
Transformation f g t =>
t -> forall (a :: k). f a -> g a
(#) m :~> g
forall (f :: * -> *) (m :: * -> *). Dual f m => m :~> f
parallel (a -> m b
f a
a)
res :: f (t b)
res = t (f b) -> f (t b)
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA (t (f b) -> f (t b)) -> t (f b) -> f (t b)
forall a b. (a -> b) -> a -> b
$ (a -> f b) -> t a -> t (f b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> f b
forall (g :: * -> *). Dual g m => a -> g b
g t a
ta
in (f :~> m) -> f (t b) -> m (t b)
forall k (f :: k -> *) (g :: k -> *) t.
Transformation f g t =>
t -> forall (a :: k). f a -> g a
(#) f :~> m
forall (f :: * -> *) (m :: * -> *). Dual f m => f :~> m
sequential f (t b)
res
parTraverse_ :: Traversable t => (a -> m b) -> t a -> m ()
parTraverse_ f :: a -> m b
f = m (t b) -> m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (m (t b) -> m ()) -> (t a -> m (t b)) -> t a -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> m b) -> t a -> m (t b)
forall (f :: * -> *) (m :: * -> *) (t :: * -> *) a b.
(Dual f m, Traversable t) =>
(a -> m b) -> t a -> m (t b)
parTraverse a -> m b
f
parSequence :: Traversable t => t (m a) -> m (t a)
parSequence = (m a -> m a) -> t (m a) -> m (t a)
forall (f :: * -> *) (m :: * -> *) (t :: * -> *) a b.
(Dual f m, Traversable t) =>
(a -> m b) -> t a -> m (t b)
parTraverse m a -> m a
forall a. a -> a
id
parSequence_ :: Traversable t => t (m a) -> m ()
parSequence_ = m (t a) -> m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (m (t a) -> m ()) -> (t (m a) -> m (t a)) -> t (m a) -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. t (m a) -> m (t a)
forall (f :: * -> *) (m :: * -> *) (t :: * -> *) a.
(Dual f m, Traversable t) =>
t (m a) -> m (t a)
parSequence
parProductR :: m a -> m b -> m b
parProductR ma :: m a
ma mb :: m b
mb = m a -> m b -> (a -> b -> b) -> m b
forall (f :: * -> *) (m :: * -> *) a0 a1 a.
Dual f m =>
m a0 -> m a1 -> (a0 -> a1 -> a) -> m a
parMap2 m a
ma m b
mb (\_ b :: b
b -> b
b)
parProductL :: m a -> m b -> m a
parProductL ma :: m a
ma mb :: m b
mb = m a -> m b -> (a -> b -> a) -> m a
forall (f :: * -> *) (m :: * -> *) a0 a1 a.
Dual f m =>
m a0 -> m a1 -> (a0 -> a1 -> a) -> m a
parMap2 m a
ma m b
mb a -> b -> a
forall a b. a -> b -> a
const
parBitraverse :: Bitraversable t => (a -> m c) -> (b -> m d) -> t a b -> m (t c d)
parBitraverse ma :: a -> m c
ma mb :: b -> m d
mb tab :: t a b
tab =
let fa :: a -> f c
fa = (\a :: a
a -> (m :~> f) -> m c -> f c
forall k (f :: k -> *) (g :: k -> *) t.
Transformation f g t =>
t -> forall (a :: k). f a -> g a
(#) m :~> f
forall (f :: * -> *) (m :: * -> *). Dual f m => m :~> f
parallel (a -> m c
ma a
a))
fb :: b -> f d
fb = (\b :: b
b -> (m :~> f) -> m d -> f d
forall k (f :: k -> *) (g :: k -> *) t.
Transformation f g t =>
t -> forall (a :: k). f a -> g a
(#) m :~> f
forall (f :: * -> *) (m :: * -> *). Dual f m => m :~> f
parallel (b -> m d
mb b
b))
res :: f (t c d)
res = (a -> f c) -> (b -> f d) -> t a b -> f (t c d)
forall (t :: * -> * -> *) (f :: * -> *) a c b d.
(Bitraversable t, Applicative f) =>
(a -> f c) -> (b -> f d) -> t a b -> f (t c d)
bitraverse a -> f c
fa b -> f d
fb t a b
tab
in (f :~> m) -> f (t c d) -> m (t c d)
forall k (f :: k -> *) (g :: k -> *) t.
Transformation f g t =>
t -> forall (a :: k). f a -> g a
(#) f :~> m
forall (f :: * -> *) (m :: * -> *). Dual f m => f :~> m
sequential f (t c d)
res
parBisequence :: Bitraversable t => t (m a) (m b) -> m (t a b)
parBisequence = (m a -> m a) -> (m b -> m b) -> t (m a) (m b) -> m (t a b)
forall (f :: * -> *) (m :: * -> *) (t :: * -> * -> *) a c b d.
(Dual f m, Bitraversable t) =>
(a -> m c) -> (b -> m d) -> t a b -> m (t c d)
parBitraverse m a -> m a
forall a. a -> a
id m b -> m b
forall a. a -> a
id
instance Semigroup e => Dual (Validation e) (Either e) where
parallel :: Either e :~> Validation e
parallel = (Either e ~> Validation e) -> Either e :~> Validation e
forall k (f :: k -> *) (g :: k -> *). (f ~> g) -> f :~> g
NT Either e ~> Validation e
forall err a. Either err a -> Validation err a
fromEither
sequential :: Validation e :~> Either e
sequential = (Validation e ~> Either e) -> Validation e :~> Either e
forall k (f :: k -> *) (g :: k -> *). (f ~> g) -> f :~> g
NT Validation e ~> Either e
forall err a. Validation err a -> Either err a
toEither
instance Dual Concurrently IO where
parallel :: IO :~> Concurrently
parallel = (IO ~> Concurrently) -> IO :~> Concurrently
forall k (f :: k -> *) (g :: k -> *). (f ~> g) -> f :~> g
NT IO ~> Concurrently
Concurrently
sequential :: Concurrently :~> IO
sequential = (Concurrently ~> IO) -> Concurrently :~> IO
forall k (f :: k -> *) (g :: k -> *). (f ~> g) -> f :~> g
NT Concurrently ~> IO
runConcurrently
instance Dual ZipList [] where
parallel :: [] :~> ZipList
parallel = ([] ~> ZipList) -> [] :~> ZipList
forall k (f :: k -> *) (g :: k -> *). (f ~> g) -> f :~> g
NT [] ~> ZipList
ZipList
sequential :: ZipList :~> []
sequential = (ZipList ~> []) -> ZipList :~> []
forall k (f :: k -> *) (g :: k -> *). (f ~> g) -> f :~> g
NT ZipList ~> []
getZipList