{-# language Safe #-}
-- |
-- Module       : Data.Smash.Internal
-- Copyright    : (c) 2020-2021 Emily Pillmore
-- License      : BSD-3-Clause
--
-- Maintainer   : Emily Pillmore <emilypi@cohomolo.gy>,
--                Asad Saeeduddin <https://github.com/masaeedu>
-- Stability    : Experimental
-- Portability  : non-portable
--
-- This module contains utilities for distributing and codistributing
-- bifunctors over monoidal actions.
--
module Data.Smash.Internal
( unzipFirst
, undecideFirst
) where

import Data.Bifunctor

unzipFirst :: Bifunctor f => f (a, b) c -> (f a c, f b c)
unzipFirst :: f (a, b) c -> (f a c, f b c)
unzipFirst f (a, b) c
fabc = (((a, b) -> a) -> f (a, b) c -> f a c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (a, b) -> a
forall a b. (a, b) -> a
fst f (a, b) c
fabc, ((a, b) -> b) -> f (a, b) c -> f b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (a, b) -> b
forall a b. (a, b) -> b
snd f (a, b) c
fabc)

undecideFirst :: Bifunctor f => Either (f a c) (f b c) -> f (Either a b) c
undecideFirst :: Either (f a c) (f b c) -> f (Either a b) c
undecideFirst (Left f a c
fac) = (a -> Either a b) -> f a c -> f (Either a b) c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first a -> Either a b
forall a b. a -> Either a b
Left f a c
fac
undecideFirst (Right f b c
fbc) = (b -> Either a b) -> f b c -> f (Either a b) c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first b -> Either a b
forall a b. b -> Either a b
Right f b c
fbc