linear-base-0.2.0: src/Data/Bifunctor/Linear/Internal/Bifunctor.hs
{-# LANGUAGE LinearTypes #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# OPTIONS_HADDOCK hide #-}
module Data.Bifunctor.Linear.Internal.Bifunctor
( Bifunctor (..),
)
where
import Prelude.Linear
-- | The Bifunctor class
--
-- == Laws
--
-- If 'bimap' is supplied, then
-- @'bimap' 'id' 'id' = 'id'@
--
-- * If 'first' and 'second' are supplied, then
-- @
-- 'first' 'id' ≡ 'id'
-- 'second' 'id' ≡ 'id'
-- @
--
-- * If all are supplied, then
-- @'bimap' f g = 'first' f '.' 'second' g
class Bifunctor p where
{-# MINIMAL bimap | (first, second) #-}
bimap :: (a %1 -> b) -> (c %1 -> d) -> a `p` c %1 -> b `p` d
bimap f g x = first f (second g x)
{-# INLINE bimap #-}
first :: (a %1 -> b) -> a `p` c %1 -> b `p` c
first f = bimap f id
{-# INLINE first #-}
second :: (b %1 -> c) -> a `p` b %1 -> a `p` c
second = bimap id
{-# INLINE second #-}
-- # Instances
-------------------------------------------------------------------------------
instance Bifunctor (,) where
bimap f g (x, y) = (f x, g y)
first f (x, y) = (f x, y)
second g (x, y) = (x, g y)
instance Bifunctor Either where
bimap f g = either (Left . f) (Right . g)