Skip to content

Commit be1de40

Browse files
authored
Merge pull request #20 from MonoidMusician/foldable-traversable
Add traversable and foldable instances
2 parents bae6b34 + d20c4c2 commit be1de40

File tree

2 files changed

+61
-3
lines changed

2 files changed

+61
-3
lines changed

package.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,5 @@
77
"devDependencies": {
88
"pulp": "^12.2.0",
99
"purescript-psa": "^0.6.0"
10-
},
11-
"dependencies": {
12-
"canvas-prebuilt": "^1.6.5-prerelease.1"
1310
}
1411
}

src/Data/Functor/Variant.purs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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)
2329
import Data.List as L
2430
import Data.Symbol (SProxy(..)) as Exports
2531
import Data.Symbol (SProxy(..), class IsSymbol, reflectSymbol)
32+
import Data.Traversable as TF
2633
import Data.Variant.Internal (class Contractable, FProxy(..), class VariantFMatchCases) as Exports
2734
import Data.Variant.Internal (class Contractable, class VariantFMatchCases, class VariantTags, FProxy, RLProxy(..), RProxy(..), VariantFCase, VariantCase, contractWith, lookup, unsafeGet, unsafeHas, variantTags)
2835
import Partial.Unsafe (unsafeCrashWith)
2936
import Type.Equality (class TypeEquals)
3037
import Type.Proxy (Proxy(..))
3138
import Type.Row as R
39+
import Prim.Row as Row
3240
import Unsafe.Coerce (unsafeCoerce)
3341

3442
newtype 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

Comments
 (0)