{-# OPTIONS_HADDOCK hide #-}
{-# LANGUAGE LinearTypes #-}
{-# LANGUAGE NoImplicitPrelude #-}
module Data.Functor.Linear.Internal.Functor
  (
    Functor(..)
  , (<$>)
  , (<$)
  , void
  ) where

import Prelude.Linear.Internal
import Prelude (Maybe(..), Either(..))
import Data.Functor.Const
import Data.Functor.Sum
import Data.Functor.Compose
import Data.Functor.Identity
import qualified Control.Monad.Trans.Reader as NonLinear
import qualified Control.Monad.Trans.Cont as NonLinear
import qualified Control.Monad.Trans.Maybe as NonLinear
import qualified Control.Monad.Trans.Except as NonLinear
import qualified Control.Monad.Trans.State.Strict as Strict
import Data.Unrestricted.Internal.Consumable

-- # Functor definition
-------------------------------------------------------------------------------

-- | Linear Data Functors should be thought of as containers holding values of
-- type @a@ over which you are able to apply a linear function of type @a %1->
-- b@ __on each__ value of type @a@ in the functor and consume a given functor
-- of type @f a@.
class Functor f where
  fmap :: (a %1-> b) -> f a %1-> f b

(<$>) :: Functor f => (a %1-> b) -> f a %1-> f b
<$> :: forall (f :: * -> *) a b. Functor f => (a %1 -> b) -> f a %1 -> f b
(<$>) = (a %1 -> b) -> f a %1 -> f b
forall (f :: * -> *) a b. Functor f => (a %1 -> b) -> f a %1 -> f b
fmap

-- | Replace all occurances of @b@ with the given @a@
-- and consume the functor @f b@.
(<$) :: (Functor f, Consumable b) => a -> f b %1-> f a
a
a <$ :: forall (f :: * -> *) b a.
(Functor f, Consumable b) =>
a -> f b %1 -> f a
<$ f b
fb = (b %1 -> a) -> f b %1 -> f a
forall (f :: * -> *) a b. Functor f => (a %1 -> b) -> f a %1 -> f b
fmap (b %1 -> a %1 -> a
forall a b. Consumable a => a %1 -> b %1 -> b
`lseq` a
a) f b
fb

-- | Discard a consumable value stored in a data functor.
void :: (Functor f, Consumable a) => f a %1-> f ()
void :: forall (f :: * -> *) a. (Functor f, Consumable a) => f a %1 -> f ()
void = (a %1 -> ()) -> f a %1 -> f ()
forall (f :: * -> *) a b. Functor f => (a %1 -> b) -> f a %1 -> f b
fmap a %1 -> ()
forall a. Consumable a => a %1 -> ()
consume

-- # Instances
-------------------------------------------------------------------------------

instance Functor [] where
  fmap :: forall a b. (a %1 -> b) -> [a] %1 -> [b]
fmap a %1 -> b
_f [] = []
  fmap a %1 -> b
f (a
a:[a]
as) = a %1 -> b
f a
a b %1 -> [b] %1 -> [b]
forall a. a -> [a] -> [a]
: (a %1 -> b) -> [a] %1 -> [b]
forall (f :: * -> *) a b. Functor f => (a %1 -> b) -> f a %1 -> f b
fmap a %1 -> b
f [a]
as

instance Functor (Const x) where
  fmap :: forall a b. (a %1 -> b) -> Const x a %1 -> Const x b
fmap a %1 -> b
_ (Const x
x) = x %1 -> Const x b
forall {k} a (b :: k). a -> Const a b
Const x
x

instance Functor Maybe where
  fmap :: forall a b. (a %1 -> b) -> Maybe a %1 -> Maybe b
fmap a %1 -> b
_ Maybe a
Nothing = Maybe b
forall a. Maybe a
Nothing
  fmap a %1 -> b
f (Just a
x) = b %1 -> Maybe b
forall a. a -> Maybe a
Just (a %1 -> b
f a
x)

instance Functor (Either e) where
  fmap :: forall a b. (a %1 -> b) -> Either e a %1 -> Either e b
fmap a %1 -> b
_ (Left e
x) = e %1 -> Either e b
forall a b. a -> Either a b
Left e
x
  fmap a %1 -> b
f (Right a
x) = b %1 -> Either e b
forall a b. b -> Either a b
Right (a %1 -> b
f a
x)

instance Functor ((,) a) where
  fmap :: forall a b. (a %1 -> b) -> (a, a) %1 -> (a, b)
fmap a %1 -> b
f (a
x,a
y) = (a
x, a %1 -> b
f a
y)

instance Functor Identity where
  fmap :: forall a b. (a %1 -> b) -> Identity a %1 -> Identity b
fmap a %1 -> b
f (Identity a
x) = b %1 -> Identity b
forall a. a -> Identity a
Identity (a %1 -> b
f a
x)

instance (Functor f, Functor g) => Functor (Sum f g) where
  fmap :: forall a b. (a %1 -> b) -> Sum f g a %1 -> Sum f g b
fmap a %1 -> b
f (InL f a
fa) = f b %1 -> Sum f g b
forall {k} (f :: k -> *) (g :: k -> *) (a :: k). f a -> Sum f g a
InL ((a %1 -> b) -> f a %1 -> f b
forall (f :: * -> *) a b. Functor f => (a %1 -> b) -> f a %1 -> f b
fmap a %1 -> b
f f a
fa)
  fmap a %1 -> b
f (InR g a
ga) = g b %1 -> Sum f g b
forall {k} (f :: k -> *) (g :: k -> *) (a :: k). g a -> Sum f g a
InR ((a %1 -> b) -> g a %1 -> g b
forall (f :: * -> *) a b. Functor f => (a %1 -> b) -> f a %1 -> f b
fmap a %1 -> b
f g a
ga)

instance (Functor f, Functor g) => Functor (Compose f g) where
  fmap :: forall a b. (a %1 -> b) -> Compose f g a %1 -> Compose f g b
fmap a %1 -> b
f (Compose f (g a)
x) = f (g b) %1 -> Compose f g b
forall {k} {k1} (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose ((g a %1 -> g b) -> f (g a) %1 -> f (g b)
forall (f :: * -> *) a b. Functor f => (a %1 -> b) -> f a %1 -> f b
fmap ((a %1 -> b) -> g a %1 -> g b
forall (f :: * -> *) a b. Functor f => (a %1 -> b) -> f a %1 -> f b
fmap a %1 -> b
f) f (g a)
x)

---------------------------------
-- Monad transformer instances --
---------------------------------

instance Functor m => Functor (NonLinear.ReaderT r m) where
  fmap :: forall a b. (a %1 -> b) -> ReaderT r m a %1 -> ReaderT r m b
fmap a %1 -> b
f (NonLinear.ReaderT r -> m a
g) = (r -> m b) %1 -> ReaderT r m b
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
NonLinear.ReaderT (\r
r -> (a %1 -> b) -> m a %1 -> m b
forall (f :: * -> *) a b. Functor f => (a %1 -> b) -> f a %1 -> f b
fmap a %1 -> b
f (r -> m a
g r
r))

-- The below transformers are all Data.Functors and all fail to be
-- Data.Applicatives without further restriction. In every case however,
-- @pure :: a -> f a@ can be defined in the standard way.
-- For @MaybeT@ and @ExceptT e@, the failure to be applicative is as detailed
-- above: @Maybe@ and @Either e@ can contain 0 or 1 elements, and so fail
-- to be applicative.
-- To give applicative instances for ContT (resp. StateT), we require the
-- parameter r (resp. s) to be Movable.

instance Functor m => Functor (NonLinear.MaybeT m) where
  fmap :: forall a b. (a %1 -> b) -> MaybeT m a %1 -> MaybeT m b
fmap a %1 -> b
f (NonLinear.MaybeT m (Maybe a)
x) = m (Maybe b) %1 -> MaybeT m b
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
NonLinear.MaybeT (m (Maybe b) %1 -> MaybeT m b) %1 -> m (Maybe b) %1 -> MaybeT m b
forall a b. (a %1 -> b) %1 -> a %1 -> b
$ (Maybe a %1 -> Maybe b) -> m (Maybe a) %1 -> m (Maybe b)
forall (f :: * -> *) a b. Functor f => (a %1 -> b) -> f a %1 -> f b
fmap ((a %1 -> b) -> Maybe a %1 -> Maybe b
forall (f :: * -> *) a b. Functor f => (a %1 -> b) -> f a %1 -> f b
fmap a %1 -> b
f) m (Maybe a)
x

instance Functor m => Functor (NonLinear.ExceptT e m) where
  fmap :: forall a b. (a %1 -> b) -> ExceptT e m a %1 -> ExceptT e m b
fmap a %1 -> b
f (NonLinear.ExceptT m (Either e a)
x) = m (Either e b) %1 -> ExceptT e m b
forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
NonLinear.ExceptT (m (Either e b) %1 -> ExceptT e m b)
%1 -> m (Either e b) %1 -> ExceptT e m b
forall a b. (a %1 -> b) %1 -> a %1 -> b
$ (Either e a %1 -> Either e b)
-> m (Either e a) %1 -> m (Either e b)
forall (f :: * -> *) a b. Functor f => (a %1 -> b) -> f a %1 -> f b
fmap ((a %1 -> b) -> Either e a %1 -> Either e b
forall (f :: * -> *) a b. Functor f => (a %1 -> b) -> f a %1 -> f b
fmap a %1 -> b
f) m (Either e a)
x

instance Functor (NonLinear.ContT r m) where
  fmap :: forall a b. (a %1 -> b) -> ContT r m a %1 -> ContT r m b
fmap a %1 -> b
f (NonLinear.ContT (a -> m r) -> m r
x) = ((b -> m r) -> m r) %1 -> ContT r m b
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
NonLinear.ContT (((b -> m r) -> m r) %1 -> ContT r m b)
%1 -> ((b -> m r) -> m r) %1 -> ContT r m b
forall a b. (a %1 -> b) %1 -> a %1 -> b
$ \b -> m r
k -> (a -> m r) -> m r
x (\a
a -> b -> m r
k (a %1 -> b
f a
a))

instance Functor m => Functor (Strict.StateT s m) where
  fmap :: forall a b. (a %1 -> b) -> StateT s m a %1 -> StateT s m b
fmap a %1 -> b
f (Strict.StateT s -> m (a, s)
x) = (s -> m (b, s)) %1 -> StateT s m b
forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a
Strict.StateT (\s
s -> ((a, s) %1 -> (b, s)) -> m (a, s) %1 -> m (b, s)
forall (f :: * -> *) a b. Functor f => (a %1 -> b) -> f a %1 -> f b
fmap (\(a
a, s
s') -> (a %1 -> b
f a
a, s
s')) (s -> m (a, s)
x s
s))