Skip to content

Commit c0ab8c8

Browse files
Add traversable and foldable instances
1 parent aef507e commit c0ab8c8

File tree

1 file changed

+48
-1
lines changed

1 file changed

+48
-1
lines changed

src/Data/Functor/Variant.purs

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@ import Prelude
1717

1818
import Control.Alternative (class Alternative, empty)
1919
import Data.List as L
20+
import Data.Monoid (class Monoid)
2021
import Data.Symbol (SProxy(..)) as Exports
21-
import Data.Symbol (SProxy, class IsSymbol, reflectSymbol)
22+
import Data.Symbol (SProxy(..), class IsSymbol, reflectSymbol)
23+
import Data.Traversable as TF
2224
import Data.Variant.Internal (class Contractable, FProxy(..), class VariantFMatchCases) as Exports
2325
import Data.Variant.Internal (class Contractable, class VariantFMatchCases, class VariantTags, FProxy, RLProxy(..), RProxy(..), VariantFCase, VariantCase, contractWith, lookup, unsafeGet, unsafeHas, variantTags)
2426
import Partial.Unsafe (unsafeCrashWith)
@@ -50,6 +52,51 @@ instance functorVariantF ∷ Functor (VariantF r) where
5052
coerceV f a. VariantFRep f a VariantF r a
5153
coerceV = unsafeCoerce
5254

55+
class FoldableVFRL (rl :: R.RowList) (row :: # Type) | rl -> row where
56+
foldMapVFRL :: forall a m. Monoid m => RLProxy rl -> (a -> m) -> VariantF row a -> m
57+
58+
instance foldableNil :: FoldableVFRL R.Nil () where
59+
foldMapVFRL _ f = case_
60+
61+
instance foldableCons ::
62+
( IsSymbol k
63+
, TF.Foldable f
64+
, FoldableVFRL rl r
65+
, RowCons k (FProxy f) r r'
66+
) => FoldableVFRL (R.Cons k (FProxy f) rl) r' where
67+
foldMapVFRL _ f = on k (TF.foldMap f) (foldMapVFRL (RLProxy :: RLProxy rl) f)
68+
where k = SProxy :: SProxy k
69+
70+
class FoldableVFRL rl row <= TraversableVFRL (rl :: R.RowList) (row :: # Type) | rl -> row where
71+
traverseVFRL :: forall f a b. Applicative f => RLProxy rl -> (a -> f b) -> VariantF row a -> f (VariantF row b)
72+
73+
instance traversableNil :: TraversableVFRL R.Nil () where
74+
traverseVFRL _ f = case_
75+
76+
instance traversableCons ::
77+
( IsSymbol k
78+
, TF.Traversable f
79+
, TraversableVFRL rl r
80+
, RowCons k (FProxy f) r r'
81+
, Union r bleh r'
82+
) => TraversableVFRL (R.Cons k (FProxy f) rl) r' where
83+
traverseVFRL _ f = on k (TF.traverse f >>> map (inj k))
84+
(traverseVFRL (RLProxy :: RLProxy rl) f >>> map expand)
85+
where k = SProxy :: SProxy k
86+
87+
instance foldableVariantF ::
88+
(R.RowToList row rl, FoldableVFRL rl row) =>
89+
TF.Foldable (VariantF row) where
90+
foldMap = foldMapVFRL (RLProxy :: RLProxy rl)
91+
foldr a = TF.foldrDefault a
92+
foldl a = TF.foldlDefault a
93+
94+
instance traversableVariantF ::
95+
(R.RowToList row rl, TraversableVFRL rl row) =>
96+
TF.Traversable (VariantF row) where
97+
traverse = traverseVFRL (RLProxy :: RLProxy rl)
98+
sequence a = TF.sequenceDefault a
99+
53100
-- | Inject into the variant at a given label.
54101
-- | ```purescript
55102
-- | maybeAtFoo :: forall r. VariantF (foo :: FProxy Maybe | r) Int

0 commit comments

Comments
 (0)