module Control.Functor.HT where

import qualified Data.Tuple.HT as Tuple
import Data.Tuple.HT (fst3, snd3, thd3)

import qualified Prelude as P
import Prelude (Functor, fmap, flip, const, (.), ($), fst, snd)


void :: Functor f => f a -> f ()
void :: f a -> f ()
void = (a -> ()) -> f a -> f ()
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (() -> a -> ()
forall a b. a -> b -> a
const ())

map :: Functor f => (a -> b) -> f a -> f b
map :: (a -> b) -> f a -> f b
map = (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap

for :: Functor f => f a -> (a -> b) -> f b
for :: f a -> (a -> b) -> f b
for = ((a -> b) -> f a -> f b) -> f a -> (a -> b) -> f b
forall a b c. (a -> b -> c) -> b -> a -> c
flip (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap


{- |
Caution:
Every pair member has a reference to the argument of 'unzip'.
Depending on the consumption pattern this may cause a memory leak.
For lists, I think, you should generally prefer 'List.unzip'.
-}
unzip :: Functor f => f (a, b) -> (f a, f b)
unzip :: f (a, b) -> (f a, f b)
unzip f (a, b)
x = (((a, b) -> a) -> f (a, b) -> f a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a, b) -> a
forall a b. (a, b) -> a
fst f (a, b)
x, ((a, b) -> b) -> f (a, b) -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a, b) -> b
forall a b. (a, b) -> b
snd f (a, b)
x)

{- |
Caution: See 'unzip'.
-}
unzip3 :: Functor f => f (a, b, c) -> (f a, f b, f c)
unzip3 :: f (a, b, c) -> (f a, f b, f c)
unzip3 f (a, b, c)
x = (((a, b, c) -> a) -> f (a, b, c) -> f a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a, b, c) -> a
forall a b c. (a, b, c) -> a
fst3 f (a, b, c)
x, ((a, b, c) -> b) -> f (a, b, c) -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a, b, c) -> b
forall a b c. (a, b, c) -> b
snd3 f (a, b, c)
x, ((a, b, c) -> c) -> f (a, b, c) -> f c
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a, b, c) -> c
forall a b c. (a, b, c) -> c
thd3 f (a, b, c)
x)


{- |
Caution: See 'unzip'.
-}
uncurry :: Functor f => (f a -> f b -> g) -> f (a, b) -> g
uncurry :: (f a -> f b -> g) -> f (a, b) -> g
uncurry f a -> f b -> g
f = (f a -> f b -> g) -> (f a, f b) -> g
forall a b c. (a -> b -> c) -> (a, b) -> c
P.uncurry f a -> f b -> g
f ((f a, f b) -> g) -> (f (a, b) -> (f a, f b)) -> f (a, b) -> g
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f (a, b) -> (f a, f b)
forall (f :: * -> *) a b. Functor f => f (a, b) -> (f a, f b)
unzip

{- |
Caution: See 'unzip'.
-}
uncurry3 :: Functor f => (f a -> f b -> f c -> g) -> f (a, b, c) -> g
uncurry3 :: (f a -> f b -> f c -> g) -> f (a, b, c) -> g
uncurry3 f a -> f b -> f c -> g
f = (f a -> f b -> f c -> g) -> (f a, f b, f c) -> g
forall a b c d. (a -> b -> c -> d) -> (a, b, c) -> d
Tuple.uncurry3 f a -> f b -> f c -> g
f ((f a, f b, f c) -> g)
-> (f (a, b, c) -> (f a, f b, f c)) -> f (a, b, c) -> g
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f (a, b, c) -> (f a, f b, f c)
forall (f :: * -> *) a b c.
Functor f =>
f (a, b, c) -> (f a, f b, f c)
unzip3


mapFst :: Functor f => (a -> f c) -> (a, b) -> f (c, b)
mapFst :: (a -> f c) -> (a, b) -> f (c, b)
mapFst a -> f c
f ~(a
a,b
b) = (c -> (c, b)) -> f c -> f (c, b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((c -> b -> (c, b)) -> b -> c -> (c, b)
forall a b c. (a -> b -> c) -> b -> a -> c
flip (,) b
b) (f c -> f (c, b)) -> f c -> f (c, b)
forall a b. (a -> b) -> a -> b
$ a -> f c
f a
a

mapSnd :: Functor f => (b -> f c) -> (a, b) -> f (a, c)
mapSnd :: (b -> f c) -> (a, b) -> f (a, c)
mapSnd b -> f c
f ~(a
a,b
b) = (c -> (a, c)) -> f c -> f (a, c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((,) a
a) (f c -> f (a, c)) -> f c -> f (a, c)
forall a b. (a -> b) -> a -> b
$ b -> f c
f b
b


mapFst3 :: Functor f => (a -> f d) -> (a,b,c) -> f (d,b,c)
mapFst3 :: (a -> f d) -> (a, b, c) -> f (d, b, c)
mapFst3 a -> f d
f ~(a
a,b
b,c
c) = (d -> (d, b, c)) -> f d -> f (d, b, c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\d
x -> (d
x,b
b,c
c)) (f d -> f (d, b, c)) -> f d -> f (d, b, c)
forall a b. (a -> b) -> a -> b
$ a -> f d
f a
a

mapSnd3 :: Functor f => (b -> f d) -> (a,b,c) -> f (a,d,c)
mapSnd3 :: (b -> f d) -> (a, b, c) -> f (a, d, c)
mapSnd3 b -> f d
f ~(a
a,b
b,c
c) = (d -> (a, d, c)) -> f d -> f (a, d, c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\d
x -> (a
a,d
x,c
c)) (f d -> f (a, d, c)) -> f d -> f (a, d, c)
forall a b. (a -> b) -> a -> b
$ b -> f d
f b
b

mapThd3 :: Functor f => (c -> f d) -> (a,b,c) -> f (a,b,d)
mapThd3 :: (c -> f d) -> (a, b, c) -> f (a, b, d)
mapThd3 c -> f d
f ~(a
a,b
b,c
c) = (d -> (a, b, d)) -> f d -> f (a, b, d)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((,,) a
a b
b) (f d -> f (a, b, d)) -> f d -> f (a, b, d)
forall a b. (a -> b) -> a -> b
$ c -> f d
f c
c


{- |
Generalization of 'Data.List.HT.outerProduct'.
-}
outerProduct ::
   (Functor f, Functor g) =>
   (a -> b -> c) -> f a -> g b -> f (g c)
outerProduct :: (a -> b -> c) -> f a -> g b -> f (g c)
outerProduct a -> b -> c
f f a
xs g b
ys = (a -> g c) -> f a -> f (g c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((b -> c) -> g b -> g c) -> g b -> (b -> c) -> g c
forall a b c. (a -> b -> c) -> b -> a -> c
flip (b -> c) -> g b -> g c
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap g b
ys ((b -> c) -> g c) -> (a -> b -> c) -> a -> g c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b -> c
f) f a
xs