11{-# LANGUAGE Trustworthy #-}
2+ {-# LANGUAGE DeriveFunctor #-}
23module Data.Crosswalk (
34 -- * Crosswalk
45 Crosswalk (.. ),
56 -- * Bicrosswalk
67 Bicrosswalk (.. ),
78 ) where
89
9- import Control.Applicative (pure , (<$>) )
10- import Data.Bifoldable (Bifoldable (.. ))
11- import Data.Bifunctor (Bifunctor (.. ))
12- import Data.Foldable (Foldable (.. ))
13- import Data.Functor.Compose (Compose (.. ))
14- import Data.Functor.Identity (Identity (.. ))
15- import Data.Vector.Generic (Vector )
16- import Prelude (Either (.. ), Functor (fmap ), Maybe (.. ), id , (.) )
17-
10+ import Control.Applicative (Applicative (pure , (<*>) ), (<$>) , Const (.. ))
11+ import Control.Monad.Trans.Maybe (MaybeT (.. ))
12+ import Data.Bifoldable (Bifoldable (.. ))
13+ import Data.Bifunctor (Bifunctor (.. ))
14+ import Data.Foldable (Foldable (.. ))
15+ import Data.Functor.Compose (Compose (.. ))
16+ import Data.Functor.Identity (Identity (.. ))
17+ import Data.Functor.Sum (Sum (.. ))
18+ import Data.Functor.These (These1 (.. ))
19+ import Data.Proxy (Proxy (.. ))
20+ import Data.Traversable (Traversable (traverse ))
21+ import Data.Vector.Generic (Vector )
22+ import Prelude (Either (.. ), Functor (fmap ), Maybe (.. ), id , (.) , uncurry , maybe )
23+
24+ import qualified Data.List.NonEmpty as NE
1825import qualified Data.Sequence as Seq
1926import qualified Data.Vector as V
2027import qualified Data.Vector.Generic as VG
@@ -55,15 +62,15 @@ instance Crosswalk [] where
5562 crosswalk f (x: xs) = alignWith cons (f x) (crosswalk f xs)
5663 where cons = these pure id (:)
5764
65+ instance Crosswalk NE. NonEmpty where
66+ crosswalk f (x NE. :| [] ) = (NE. :| [] ) <$> f x
67+ crosswalk f (x1 NE. :| x2 : xs) = alignWith cons (f x1) (crosswalk f (x2 NE. :| xs))
68+ where cons = these (NE. :| [] ) id (NE. <|)
69+
5870instance Crosswalk Seq. Seq where
5971 crosswalk f = foldr (alignWith cons . f) nil where
6072 cons = these Seq. singleton id (Seq. <|)
6173
62- instance Crosswalk (These a ) where
63- crosswalk _ (This _) = nil
64- crosswalk f (That x) = That <$> f x
65- crosswalk f (These a x) = These a <$> f x
66-
6774crosswalkVector :: (Vector v a , Vector v b , Align f )
6875 => (a -> f b ) -> v a -> f (v b )
6976crosswalkVector f = fmap VG. fromList . VG. foldr (alignWith cons . f) nil where
@@ -72,18 +79,55 @@ crosswalkVector f = fmap VG.fromList . VG.foldr (alignWith cons . f) nil where
7279instance Crosswalk V. Vector where
7380 crosswalk = crosswalkVector
7481
82+ instance Crosswalk (Either e ) where
83+ crosswalk _ (Left _) = nil
84+ crosswalk f (Right x) = Right <$> f x
85+
86+ instance Crosswalk (These a ) where
87+ crosswalk _ (This _) = nil
88+ crosswalk f (That x) = That <$> f x
89+ crosswalk f (These a x) = These a <$> f x
90+
7591instance Crosswalk ((,) a ) where
7692 crosswalk fun (a, x) = fmap ((,) a) (fun x)
7793
7894-- can't (shouldn't) do longer tuples until there are Functor and Foldable
7995-- instances for them
8096
97+ instance Crosswalk Proxy where
98+ crosswalk _ _ = nil
99+
100+ instance Crosswalk (Const r ) where
101+ crosswalk _ _ = nil
102+
103+ instance (Crosswalk f , Crosswalk g ) => Crosswalk (Sum f g ) where
104+ crosswalk f (InL xs) = InL <$> crosswalk f xs
105+ crosswalk f (InR xs) = InR <$> crosswalk f xs
106+
107+ instance (Crosswalk f , Crosswalk g ) => Crosswalk (These1 f g ) where
108+ crosswalk f (This1 xs) = This1 <$> crosswalk f xs
109+ crosswalk f (That1 ys) = That1 <$> crosswalk f ys
110+ crosswalk f (These1 xs ys) = alignWith go (crosswalk f xs) (crosswalk f ys)
111+ where go = these This1 That1 These1
112+
81113instance (Crosswalk f , Crosswalk g ) => Crosswalk (Compose f g ) where
82114 crosswalk f
83115 = fmap Compose -- can't coerce: maybe the Align-able thing has role nominal
84116 . crosswalk (crosswalk f)
85117 . getCompose
86118
119+ data Fill f a = Fill a (f a )
120+ deriving (Functor )
121+
122+ instance Align f => Applicative (Fill f ) where
123+ pure x = Fill x nil
124+ Fill deff fs <*> Fill defx xs
125+ = Fill (deff defx) (alignWith (uncurry id . fromThese deff defx) fs xs)
126+
127+ instance Traversable t => Crosswalk (MaybeT t ) where
128+ crosswalk f (MaybeT xs) = case traverse go xs of Fill _ ys -> MaybeT <$> ys
129+ where go mx = Fill Nothing (Just <$> maybe nil f mx)
130+
87131-- --------------------------------------------------------------------------
88132-- | Bifoldable bifunctors supporting traversal through an alignable
89133-- functor.
@@ -113,3 +157,6 @@ instance Bicrosswalk These where
113157 bicrosswalk f _ (This x) = This <$> f x
114158 bicrosswalk _ g (That x) = That <$> g x
115159 bicrosswalk f g (These x y) = align (f x) (g y)
160+
161+ instance Bicrosswalk Const where
162+ bicrosswalk f _ (Const x) = Const <$> f x
0 commit comments