fresnel-0.1.0.0: src/Fresnel/Traversal1.hs
{-# LANGUAGE RankNTypes #-}
module Fresnel.Traversal1
( -- * Relevant traversals
Traversal1
, Traversal1'
, IsTraversal1
-- * Construction
, traversal1
, traversed1
, backwards
, both
, beside
-- * Elimination
, traverse1Of
, for1Of
, sequence1Of
, transposeOf
) where
import Control.Applicative.Backwards
import Data.Functor.Apply
import Data.List.NonEmpty (NonEmpty(..), zipWith)
import Data.Profunctor.Unsafe ((#.), (.#))
import Data.Semigroup.Bitraversable
import Data.Semigroup.Traversable
import Fresnel.Optic
import Fresnel.Profunctor.Star1 (Star1(..))
import Fresnel.Profunctor.Traversing1
import Fresnel.Traversal1.Internal
import Prelude hiding (zipWith)
-- Relevant traversals
type Traversal1 s t a b = forall p . IsTraversal1 p => Optic p s t a b
type Traversal1' s a = Traversal1 s s a a
-- Construction
traversal1 :: (forall f . Apply f => (a -> f b) -> (s -> f t)) -> Traversal1 s t a b
traversal1 f = wander1 f
traversed1 :: Traversable1 t => Traversal1 (t a) (t b) a b
traversed1 = traversal1 traverse1
-- | Reverse the order in which a (finite) 'Traversal1' is traversed.
--
-- @
-- 'backwards' . 'backwards' = 'id'
-- @
backwards :: Traversal1 s t a b -> Traversal1 s t a b
backwards o = traversal1 (\ f -> forwards #. traverse1Of o (Backwards #. f))
both :: Bitraversable1 r => Traversal1 (r a a) (r b b) a b
both = traversal1 (\ f -> bitraverse1 f f)
beside :: Bitraversable1 r => Traversal1 s1 t1 a b -> Traversal1 s2 t2 a b -> Traversal1 (r s1 s2) (r t1 t2) a b
beside l r = traversal1 (\ f -> bitraverse1 (traverse1Of l f) (traverse1Of r f))
-- Elimination
-- | Map over the targets of an 'Fresnel.Iso.Iso', 'Fresnel.Lens.Lens', 'Fresnel.Optional.Optional', or 'Traversal', collecting the results.
--
-- @
-- 'traverse1Of' . 'traversal1' = 'id'
-- 'traverse1Of' 'traversed1' = 'traverse1'
-- @
traverse1Of :: Apply f => Traversal1 s t a b -> ((a -> f b) -> (s -> f t))
traverse1Of o = runStar1 #. o .# Star1
for1Of :: Apply f => Traversal1 s t a b -> (s -> (a -> f b) -> f t)
for1Of o = flip (traverse1Of o)
sequence1Of :: Apply f => Traversal1 s t (f b) b -> (s -> f t)
sequence1Of o = traverse1Of o id
transposeOf :: Traversal1 s t (NonEmpty a) a -> s -> NonEmpty t
transposeOf o = getZipList #. traverse1Of o ZipList
newtype ZipList a = ZipList { getZipList :: NonEmpty a }
instance Functor ZipList where
fmap f (ZipList as) = ZipList (fmap f as)
instance Apply ZipList where
liftF2 f (ZipList as) (ZipList bs) = ZipList (zipWith f as bs)