Skip to content

Commit 0141ad1

Browse files
committed
Add applicative operators
1 parent 1050782 commit 0141ad1

File tree

1 file changed

+28
-2
lines changed

1 file changed

+28
-2
lines changed

Data/Codec/Codec.hs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ module Data.Codec.Codec
1010
, PartialCodec, cbuild, assume, covered, (<->), produceMaybe
1111
-- * Codec combinators
1212
, opt, mapCodec, mapCodecF, mapCodecM
13+
, mapCodec', comapCodec', (=.)
1314
)
1415
where
1516

@@ -51,8 +52,7 @@ opt (Codec r w) = Codec (optional r) (maybe (pure ()) w)
5152

5253
-- | Turn a @`Codec` a@ into a @`Codec` b@ by providing an isomorphism.
5354
mapCodec :: Functor fr => (a -> b) -> (b -> a) -> Codec fr fw a -> Codec fr fw b
54-
mapCodec to from (Codec r w)
55-
= Codec (to <$> r) (w . from)
55+
mapCodec = mapCodec'
5656

5757
-- | Map a field codec monadically. Useful for error handling but care must be taken to make sure that
5858
-- the results are still complementary.
@@ -65,6 +65,32 @@ mapCodecF :: (fr a -> gr a) -> (fw () -> gw ()) -> Codec fr fw a -> Codec gr gw
6565
mapCodecF fr fw (Codec r w)
6666
= Codec (fr r) (fw . w)
6767

68+
-- | Independently map the two components of a `Codec'`.
69+
--
70+
-- Generalizes `mapCodec`.
71+
mapCodec' :: Functor fr => (a -> b) -> (c -> d) -> Codec' fr fw d a -> Codec' fr fw c b
72+
mapCodec' to from (Codec r w)
73+
= Codec (to <$> r) (w . from)
74+
75+
-- | Map on the `produce` component of a `Codec`.
76+
--
77+
-- @
78+
-- comapCodec' = mapCodec' id
79+
-- @
80+
--
81+
-- But `comapCodec'` does not require a `Functor` constraint.
82+
comapCodec' :: (c -> d) -> Codec' fr fw d a -> Codec' fr fw c a
83+
comapCodec' from (Codec r w)
84+
= Codec r (w . from)
85+
86+
-- | Infix synonym of `comapCodec'`.
87+
--
88+
-- The symbol mimics a record-like syntax in applicative definitions.
89+
(=.) :: (b -> a') -> Codec' fr fw a' a -> Codec' fr fw b a
90+
(=.) = comapCodec'
91+
92+
infixr 5 =.
93+
6894
-- | A codec where `a` can be produced from a concrete value of `b` in context `f`,
6995
-- and a concrete type of value `b` can always be produced.
7096
type ConcreteCodec b f a = Codec (ReaderT b f) (Const b) a

0 commit comments

Comments
 (0)