Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract 'dsumEncoder' from chainEncoder #1000

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 22 additions & 15 deletions lib/route/src/Obelisk/Route.hs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ module Obelisk.Route
, pathSegmentEncoder
, queryOnlyEncoder
, Decoder(..)
, dsumEncoder
, dmapEncoder
, fieldMapEncoder
, pathFieldEncoder
Expand Down Expand Up @@ -626,30 +627,36 @@ pathComponentEncoderImpl =
chainEncoder (lensEncoder (\(_, b) a -> (a, b)) Prelude.fst consEncoder)

--NOTE: Naming convention in this module is to always talk about things in the *encoding* direction, never in the *decoding* direction
dsumEncoder
:: forall check parse f g a b.
( Functor check
, Monad parse
)
=> Encoder check parse (Some f) a
-> (forall x. f x -> Encoder Identity parse (g x) b)
-> Encoder check parse (DSum f g) (a, b)
dsumEncoder this rest = Encoder $ do
thisValid <- unEncoder this
pure $ EncoderImpl
{ _encoderImpl_decode = \(here, following) -> do
_encoderImpl_decode thisValid here >>= \(Some r) ->
(r :=>) <$> _encoderImpl_decode (runIdentity . unEncoder $ rest r) following
, _encoderImpl_encode = \(r :=> s) ->
( _encoderImpl_encode thisValid $ Some r
, _encoderImpl_encode (runIdentity . unEncoder $ rest r) s
)
}

chainEncoder
:: forall check parse p r b.
( Monad check
( Applicative check
, Monad parse
)
=> Encoder check parse (b, r) r
-> Encoder check parse (Some p) b
-> (forall a. p a -> Encoder Identity parse a r)
-> Encoder check parse (R p) r
chainEncoder cons this rest = Encoder $ do
consValid <- unEncoder cons
thisValid <- unEncoder this
pure $ EncoderImpl
{ _encoderImpl_decode = \v -> do
(here, following) <- _encoderImpl_decode consValid v
_encoderImpl_decode thisValid here >>= \case
Some r ->
(r :/) <$> _encoderImpl_decode (runIdentity . unEncoder $ rest r) following
, _encoderImpl_encode = \(r :/ s) ->
_encoderImpl_encode consValid
( _encoderImpl_encode thisValid $ Some r
, _encoderImpl_encode (runIdentity . unEncoder $ rest r) s)
}
chainEncoder cons this rest = cons . dsumEncoder this (\p -> rest p . unwrappedEncoder)

--TODO: Do this in terms of a lens instead
lensEncoder :: (Applicative check, Monad parse)
Expand Down