@@ -14,6 +14,12 @@ module Data.Functor.Variant
1414 , unvariantF
1515 , revariantF
1616 , class VariantFShows , variantFShows
17+ , class TraversableVFRL
18+ , class FoldableVFRL
19+ , traverseVFRL
20+ , foldrVFRL
21+ , foldlVFRL
22+ , foldMapVFRL
1723 , module Exports
1824 ) where
1925
@@ -23,12 +29,14 @@ import Control.Alternative (class Alternative, empty)
2329import Data.List as L
2430import Data.Symbol (SProxy (..)) as Exports
2531import Data.Symbol (SProxy (..), class IsSymbol , reflectSymbol )
32+ import Data.Traversable as TF
2633import Data.Variant.Internal (class Contractable , FProxy (..), class VariantFMatchCases ) as Exports
2734import Data.Variant.Internal (class Contractable , class VariantFMatchCases , class VariantTags , FProxy , RLProxy (..), RProxy (..), VariantFCase , VariantCase , contractWith , lookup , unsafeGet , unsafeHas , variantTags )
2835import Partial.Unsafe (unsafeCrashWith )
2936import Type.Equality (class TypeEquals )
3037import Type.Proxy (Proxy (..))
3138import Type.Row as R
39+ import Prim.Row as Row
3240import Unsafe.Coerce (unsafeCoerce )
3341
3442newtype VariantFRep f a = VariantFRep
@@ -56,6 +64,59 @@ instance functorVariantF ∷ Functor (VariantF r) where
5664 coerceV ∷ ∀ f a . VariantFRep f a → VariantF r a
5765 coerceV = unsafeCoerce
5866
67+ class FoldableVFRL (rl :: R.RowList ) (row :: # Type ) | rl -> row where
68+ foldrVFRL :: forall a b . RLProxy rl -> (a -> b -> b ) -> b -> VariantF row a -> b
69+ foldlVFRL :: forall a b . RLProxy rl -> (b -> a -> b ) -> b -> VariantF row a -> b
70+ foldMapVFRL :: forall a m . Monoid m => RLProxy rl -> (a -> m ) -> VariantF row a -> m
71+
72+ instance foldableNil :: FoldableVFRL R.Nil () where
73+ foldrVFRL _ _ _ = case_
74+ foldlVFRL _ _ _ = case_
75+ foldMapVFRL _ _ = case_
76+
77+ instance foldableCons ::
78+ ( IsSymbol k
79+ , TF.Foldable f
80+ , FoldableVFRL rl r
81+ , Row.Cons k (FProxy f ) r r'
82+ ) => FoldableVFRL (R.Cons k (FProxy f ) rl ) r' where
83+ foldrVFRL _ f b = on k (TF .foldr f b) (foldrVFRL (RLProxy :: RLProxy rl ) f b)
84+ where k = SProxy :: SProxy k
85+ foldlVFRL _ f b = on k (TF .foldl f b) (foldlVFRL (RLProxy :: RLProxy rl ) f b)
86+ where k = SProxy :: SProxy k
87+ foldMapVFRL _ f = on k (TF .foldMap f) (foldMapVFRL (RLProxy :: RLProxy rl ) f)
88+ where k = SProxy :: SProxy k
89+
90+ class FoldableVFRL rl row <= TraversableVFRL (rl :: R.RowList ) (row :: # Type ) | rl -> row where
91+ traverseVFRL :: forall f a b . Applicative f => RLProxy rl -> (a -> f b ) -> VariantF row a -> f (VariantF row b )
92+
93+ instance traversableNil :: TraversableVFRL R.Nil () where
94+ traverseVFRL _ f = case_
95+
96+ instance traversableCons ::
97+ ( IsSymbol k
98+ , TF.Traversable f
99+ , TraversableVFRL rl r
100+ , Row.Cons k (FProxy f ) r r'
101+ , R.Union r rx r'
102+ ) => TraversableVFRL (R.Cons k (FProxy f ) rl ) r' where
103+ traverseVFRL _ f = on k (TF .traverse f >>> map (inj k))
104+ (traverseVFRL (RLProxy :: RLProxy rl ) f >>> map expand)
105+ where k = SProxy :: SProxy k
106+
107+ instance foldableVariantF ::
108+ (R.RowToList row rl , FoldableVFRL rl row ) =>
109+ TF.Foldable (VariantF row ) where
110+ foldr = foldrVFRL (RLProxy :: RLProxy rl )
111+ foldl = foldlVFRL (RLProxy :: RLProxy rl )
112+ foldMap = foldMapVFRL (RLProxy :: RLProxy rl )
113+
114+ instance traversableVariantF ::
115+ (R.RowToList row rl , TraversableVFRL rl row ) =>
116+ TF.Traversable (VariantF row ) where
117+ traverse = traverseVFRL (RLProxy :: RLProxy rl )
118+ sequence = TF .sequenceDefault
119+
59120-- | Inject into the variant at a given label.
60121-- | ```purescript
61122-- | maybeAtFoo :: forall r. VariantF (foo :: FProxy Maybe | r) Int
0 commit comments