{-# LANGUAGE RankNTypes #-}
module FFunctor.Lift1 where

import FFunctor
import Data.Bifunctor (Bifunctor(..))

newtype Lift1 ff g x = Lift1 { forall (ff :: (* -> *) -> * -> *) (g :: * -> *) x.
Lift1 ff g x -> Either (g x) (ff g x)
runLift1 :: Either (g x) (ff g x) }

instance (Functor g, Functor (ff g)) => Functor (Lift1 ff g) where
  fmap :: forall a b. (a -> b) -> Lift1 ff g a -> Lift1 ff g b
fmap a -> b
t = Either (g b) (ff g b) -> Lift1 ff g b
forall (ff :: (* -> *) -> * -> *) (g :: * -> *) x.
Either (g x) (ff g x) -> Lift1 ff g x
Lift1 (Either (g b) (ff g b) -> Lift1 ff g b)
-> (Lift1 ff g a -> Either (g b) (ff g b))
-> Lift1 ff g a
-> Lift1 ff g b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (g a -> g b)
-> (ff g a -> ff g b)
-> Either (g a) (ff g a)
-> Either (g b) (ff g b)
forall a b c d. (a -> b) -> (c -> d) -> Either a c -> Either b d
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap ((a -> b) -> g a -> g b
forall a b. (a -> b) -> g a -> g b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
t) ((a -> b) -> ff g a -> ff g b
forall a b. (a -> b) -> ff g a -> ff g b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
t) (Either (g a) (ff g a) -> Either (g b) (ff g b))
-> (Lift1 ff g a -> Either (g a) (ff g a))
-> Lift1 ff g a
-> Either (g b) (ff g b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Lift1 ff g a -> Either (g a) (ff g a)
forall (ff :: (* -> *) -> * -> *) (g :: * -> *) x.
Lift1 ff g x -> Either (g x) (ff g x)
runLift1

instance FFunctor ff => FFunctor (Lift1 ff) where
  ffmap :: forall (g :: * -> *) (h :: * -> *) x.
(Functor g, Functor h) =>
(g ~> h) -> Lift1 ff g x -> Lift1 ff h x
ffmap g ~> h
gh = Either (h x) (ff h x) -> Lift1 ff h x
forall (ff :: (* -> *) -> * -> *) (g :: * -> *) x.
Either (g x) (ff g x) -> Lift1 ff g x
Lift1 (Either (h x) (ff h x) -> Lift1 ff h x)
-> (Lift1 ff g x -> Either (h x) (ff h x))
-> Lift1 ff g x
-> Lift1 ff h x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (g x -> h x)
-> (ff g x -> ff h x)
-> Either (g x) (ff g x)
-> Either (h x) (ff h x)
forall a b c d. (a -> b) -> (c -> d) -> Either a c -> Either b d
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap g x -> h x
g ~> h
gh ((g ~> h) -> ff g x -> ff h x
forall (g :: * -> *) (h :: * -> *) x.
(Functor g, Functor h) =>
(g ~> h) -> ff g x -> ff h x
forall (ff :: (* -> *) -> * -> *) (g :: * -> *) (h :: * -> *) x.
(FFunctor ff, Functor g, Functor h) =>
(g ~> h) -> ff g x -> ff h x
ffmap g x -> h x
g ~> h
gh) (Either (g x) (ff g x) -> Either (h x) (ff h x))
-> (Lift1 ff g x -> Either (g x) (ff g x))
-> Lift1 ff g x
-> Either (h x) (ff h x)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Lift1 ff g x -> Either (g x) (ff g x)
forall (ff :: (* -> *) -> * -> *) (g :: * -> *) x.
Lift1 ff g x -> Either (g x) (ff g x)
runLift1