1
1
{-# LANGUAGE Trustworthy #-}
2
+ {-# LANGUAGE DeriveFunctor #-}
2
3
module Data.Crosswalk (
3
4
-- * Crosswalk
4
5
Crosswalk (.. ),
5
6
-- * Bicrosswalk
6
7
Bicrosswalk (.. ),
7
8
) where
8
9
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
18
25
import qualified Data.Sequence as Seq
19
26
import qualified Data.Vector as V
20
27
import qualified Data.Vector.Generic as VG
@@ -55,15 +62,15 @@ instance Crosswalk [] where
55
62
crosswalk f (x: xs) = alignWith cons (f x) (crosswalk f xs)
56
63
where cons = these pure id (:)
57
64
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
+
58
70
instance Crosswalk Seq. Seq where
59
71
crosswalk f = foldr (alignWith cons . f) nil where
60
72
cons = these Seq. singleton id (Seq. <|)
61
73
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
-
67
74
crosswalkVector :: (Vector v a , Vector v b , Align f )
68
75
=> (a -> f b ) -> v a -> f (v b )
69
76
crosswalkVector 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
72
79
instance Crosswalk V. Vector where
73
80
crosswalk = crosswalkVector
74
81
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
+
75
91
instance Crosswalk ((,) a ) where
76
92
crosswalk fun (a, x) = fmap ((,) a) (fun x)
77
93
78
94
-- can't (shouldn't) do longer tuples until there are Functor and Foldable
79
95
-- instances for them
80
96
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
+
81
113
instance (Crosswalk f , Crosswalk g ) => Crosswalk (Compose f g ) where
82
114
crosswalk f
83
115
= fmap Compose -- can't coerce: maybe the Align-able thing has role nominal
84
116
. crosswalk (crosswalk f)
85
117
. getCompose
86
118
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
+
87
131
-- --------------------------------------------------------------------------
88
132
-- | Bifoldable bifunctors supporting traversal through an alignable
89
133
-- functor.
@@ -113,3 +157,6 @@ instance Bicrosswalk These where
113
157
bicrosswalk f _ (This x) = This <$> f x
114
158
bicrosswalk _ g (That x) = That <$> g x
115
159
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