Skip to content

Add decoding utils#984

Open
alexfmpe wants to merge 4 commits into
obsidiansystems:developfrom
alexfmpe:decoding-utils
Open

Add decoding utils#984
alexfmpe wants to merge 4 commits into
obsidiansystems:developfrom
alexfmpe:decoding-utils

Conversation

@alexfmpe
Copy link
Copy Markdown
Contributor

Original motivation was supporting some kind of canonicalization to allow each route to be decoded to from several urls. A lot of semantic agony later, this is what I ended up with.

I have:

  • Based work on latest develop branch
  • Followed the contribution guide
  • Looked for lint in my changes with hlint . (lint found code you did not write can be left alone)
  • Run the test suite: $(nix-build -A selftest --no-out-link)
  • Updated the changelog
  • (Optional) Run CI tests locally: nix-build release.nix -A build.x86_64-linux --no-out-link (or x86_64-darwin on macOS)

=> (err -> (b -> parse a) -> (b -> parse a))
-> Encoder check parse a b
-> Encoder check parse a b
retryEncoder retry = unsafeWrapDecoding $ \p b -> catchError (p b) $ \e -> retry e p b
Copy link
Copy Markdown
Contributor Author

@alexfmpe alexfmpe Sep 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note this only satisfies unsafeWrapDecoding's law if we can trust MonadError to preserve success (well, non-failure). Which I wager we should, but the documentation has no laws whatsoever.
Currently being discussed in the mailing list: https://mail.haskell.org/pipermail/libraries/2022-September/031621.html

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good enough

-- Thus, to produce a law-abiding encoder, we need only preserve parse success.
unsafeWrapDecoding
:: Functor check
=> ((b -> parse a) -> (b -> parse' a)) -- ^ Required law for @wrap@ argument: @forall a b. p b = pure a => wrap p b = pure a@
Copy link
Copy Markdown
Contributor Author

@alexfmpe alexfmpe Sep 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems hoistParse also implicitly relies on a simplified version of this law, having wrap = (f,). For instance

hoistParse $ const $ throwError "bla"

will break roundtrips when we're encoding from inhabited types.
Should it be renamed to have an unsafe prefix?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, with deprecation


-- | Completely override the decoding function.
-- Since the only 'Encoder' law is round-tripping, values that fail to parse are unconstrained.
-- Thus, to produce a law-abiding encoder, we need only preserve parse success.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"preserve the value of successful parses", not just their successfulness

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants