fresnel-0.1.0.0: src/Fresnel/Profunctor/Traversing1.hs
{-# LANGUAGE RankNTypes #-}
module Fresnel.Profunctor.Traversing1
( Traversing1(..)
-- ** Profunctor from Traversing1
, dimapTraversing1
, lmapTraversing1
, rmapTraversing1
-- ** Strong from Traversing1
, firstTraversing1
, secondTraversing1
) where
import Control.Arrow (Kleisli(..))
import Data.Functor.Apply
import Data.Functor.Const
import Data.Functor.Identity
import Data.Profunctor (Forget(..), Star(..), Strong)
import Data.Profunctor.Unsafe ((#.))
import Fresnel.Profunctor.OptionalStar (OptionalStar(..))
class Strong p => Traversing1 p where
wander1 :: (forall f . Apply f => (a -> f b) -> (s -> f t)) -> (p a b -> p s t)
instance Traversing1 (->) where
wander1 f g = runIdentity . f (Identity . g)
instance Monad m => Traversing1 (Kleisli m) where
wander1 f (Kleisli k) = Kleisli (unwrapApplicative . f (WrapApplicative . k))
instance Semigroup r => Traversing1 (Forget r) where
wander1 f (Forget k) = Forget (getConst #. f (Const #. k))
instance Applicative f => Traversing1 (Star f) where
wander1 f (Star k) = Star (unwrapApplicative . f (WrapApplicative . k))
instance Apply f => Traversing1 (OptionalStar f) where
wander1 f (OptionalStar k) = OptionalStar (\ k' -> k (\ p -> k' p . f))
-- Profunctor from Traversing1
dimapTraversing1 :: Traversing1 p => (a' -> a) -> (b -> b') -> (p a b -> p a' b')
dimapTraversing1 f g = wander1 (\ k -> fmap g . k . f)
lmapTraversing1 :: Traversing1 p => (a' -> a) -> (p a b -> p a' b)
lmapTraversing1 f = wander1 (. f)
rmapTraversing1 :: Traversing1 p => (b -> b') -> (p a b -> p a b')
rmapTraversing1 f = wander1 (fmap f .)
-- Strong from Traversing1
firstTraversing1 :: Traversing1 p => p a b -> p (a, c) (b, c)
firstTraversing1 = wander1 (\ k (a, c) -> flip (,) c <$> k a)
secondTraversing1 :: Traversing1 p => p a b -> p (c, a) (c, b)
secondTraversing1 = wander1 (\ k (c, a) -> (,) c <$> k a)