{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
module Control.FX.Functor.Class (
Commutant(..)
, Bifunctor(..)
, IsMaybe(..)
, Wrap(..)
, Renaming(..)
) where
class
( Functor d
) => Commutant d
where
commute
:: (Applicative f)
=> d (f a) -> f (d a)
instance
Commutant Maybe
where
commute
:: ( Applicative f )
=> Maybe (f a) -> f (Maybe a)
commute x = case x of
Nothing -> pure Nothing
Just m -> fmap Just m
instance
Commutant (Either e)
where
commute
:: ( Applicative f )
=> Either e (f a) -> f (Either e a)
commute x = case x of
Left e -> pure (Left e)
Right m -> fmap Right m
class
Bifunctor (f :: * -> * -> *)
where
bimap1 :: (a -> c) -> f a b -> f c b
bimap2 :: (b -> c) -> f a b -> f a c
instance
Bifunctor Either
where
bimap1
:: (a -> c)
-> Either a b
-> Either c b
bimap1 f x = case x of
Left a -> Left (f a)
Right b -> Right b
bimap2
:: (b -> c)
-> Either a b
-> Either a c
bimap2 f x = case x of
Left a -> Left a
Right b -> Right (f b)
instance
Bifunctor (,)
where
bimap1
:: (a -> c)
-> (a,b)
-> (c,b)
bimap1 f (a,b) = (f a, b)
bimap2
:: (b -> c)
-> (a,b)
-> (a,c)
bimap2 f (a,b) = (a, f b)
class
IsMaybe (f :: * -> *)
where
fromMaybe :: Maybe a -> f a
toMaybe :: f a -> Maybe a
instance
IsMaybe Maybe
where
fromMaybe
:: Maybe a
-> Maybe a
fromMaybe = id
toMaybe
:: Maybe a
-> Maybe a
toMaybe = id
newtype Wrap f a = Wrap
{ unWrap :: f a }
class Renaming f where
namingMap :: a -> f a
namingInv :: f a -> a
instance
( Renaming f
) => Functor (Wrap f)
where
fmap f =
Wrap . namingMap . f . namingInv . unWrap
instance
( Renaming f
) => Applicative (Wrap f)
where
pure = Wrap . namingMap
f <*> x =
Wrap $ namingMap $
(namingInv $ unWrap f)
(namingInv $ unWrap x)
instance
( Renaming f
) => Monad (Wrap f)
where
return = Wrap . namingMap
x >>= f =
f (namingInv $ unWrap x)
instance
( Renaming f, Eq a
) => Eq (Wrap f a)
where
x == y =
(namingInv $ unWrap x) == (namingInv $ unWrap y)
instance
( Renaming f, Semigroup a
) => Semigroup (Wrap f a)
where
x <> y = Wrap . namingMap $
(namingInv $ unWrap x) <> (namingInv $ unWrap y)
instance
( Renaming f, Monoid a
) => Monoid (Wrap f a)
where
mempty = Wrap $ namingMap mempty