Comments (6)
@splodingsocks - I listened to your Elm podcast for awhile, so I know you've dabbled with Purescript and Haskell and whatnot, so you're familiar with some of the underlying FP concepts. I just wanted to throw out another library that @mlms13 and I are working on called Relude. It's basically a more purescript/haskell/FP-inspired prelude for Reason that tries to provide more of the FP stuff that's not in the normal Reason stdlib and Belt.
I think what you are asking for is related to the FP typeclass Traversable
, specifically the sequence
function to "flip the containers", like array(Result.t) -> Result(array)
.
However, it appears that you want a type that can collect both the successful Json decode results and the errors (rather than a Result
that fails fast with a single error or single success, or a Validation with a Nel of errors
that either collects errors, or a single successful result), and there is a type that is suited for that purpose called Ior
(inclusive or). We have a type like that in Relude called ResultIor
(not a great name) which looks a lot like the Belt.Result
but it has the "collect both errors and successes" semantics in the applicative.
https://github.com/reazen/relude/blob/master/src/Relude_ResultIor.re
Anyway, I wanted to make you aware of this library as you might be interested. I think we are actually fairly close to having something reasonable to release, probably as a 0.x version, and we'd love feedback and contributions if you think it's valuable.
from bs-decode.
Yeah, I like the idea of adding more helper functions to work with decoders themselves (and their output). I definitely agree with your suggestion on Discord to add map
to the decoder itself, and I like the idea of adding a helper to traverse/sequence output arrays/lists etc.
Also, internally we have a decodeTolerantList
that filters out failures instead of failing the whole thing (kind of the opposite of what you're asking for here 😄 ).
So anyway, 👍 . There's definitely value in providing more common utilities out of the box.
from bs-decode.
Wow, you guys have done a whole stinking' lot of work on that library. Way to go!
from bs-decode.
Re Ior
, I think in this case I was looking more for a type that would either be a list of results, or a list of errors, not both errors and data at the same time. Failing fast would be fine though, too.
If I were okay with a fail fast I could just write another utility function that would return a result of either the list of decoded data, or the first failure. Is that what you're saying? There's not already a function for that, is there?
from bs-decode.
If I'm understanding correctly, I think what you are looking for is the same as the traverse
function you get from the Traversable
typeclass int the FP world. Whenever you see a situation where you are "flipping containers" of data, it's typically a Traversable
situation, using either traverse
or sequence
.
I'm not saying you should use relude or a heavier weight library for this small purpose, but you can get "fail fast" or "collect errors" or "collect errors and successes" behavior depending on the type you use and it's applicative implementation/semantics.
For fail fast, you use Result
with the Traversable
because Result
's applicative has fail-fast semantics, and the traverse function looks like this:
https://github.com/reazen/relude/blob/master/src/Relude_ListF.re#L109-L123
This basically gives you list(Json.t) => (Json.t => Result.t(a, e)) => Result.t(list(a), e)
Since it's fail fast, you only get the one e
in the final Result
, not a collection of errors.
If you want the ability to collect either errors or all successes, you can use something like Validation
with the Traversable
, because Validation
's applicative has the "collect errors in a Semigroup
semantics". In this case the Semigroup
is a NonEmptyList
because you can guarantee that if it fails, you should have at least one error there.
https://github.com/reazen/relude/blob/master/src/Relude_ListF.re#L150-L165
This basically gives you: list(Json.t) => (Json.t => Result.t(a, e)) => Validation.t(list(a), NonEmptyList(e))
(Note that this function signature is kind of a specialization of the general traverse
signature, where the intermediate Result
gets lifted into a Validation
internally.)
We don't have the Ior
/list
version of Traversable
that collects both errors and successes specialized like this in Relude at this point, but it would be a similar implementation. This is the big downside of ocaml/reason's "Module Functor" approach - you don't get the automatic typeclass resolution like you would in purescript/scala/haskell/etc., so you have to assemble these things by hand, or specialize them like this.
I don't think this really helps your immediate need, but just wanted to explain how the use of typeclasses can give you these types of things for free (mostly). I'm just trying to convince you that if you have the right prelude/stdlib, libraries like this don't need to provide these types of helper functions 😃
from bs-decode.
I've been leaning toward slimming down bs-decode
to just decoders (e.g. Decode.ResultUtil
is no longer part of the public interface). We've been putting a decent amount of work into Relude, so I think I'm leaning toward encouraging people to use that for utility functions.
In this case, if you have array(Result.t(v, err))
, you can flip it to Result.t(array(v), err)
with Relude.Array.Result.sequence
(which is part of the Traversable
module, as @andywhite37 was saying).
from bs-decode.
Related Issues (20)
- Plan for v2 HOT 11
- Report errors as JSON HOT 1
- Implement MonadThrow
- Deprecate tuple decoders HOT 1
- Rethink custom/extensible validations HOT 1
- Deprecate mapN, NonEmptyList, ParseError.ResultOf
- Add a null decoder HOT 1
- Add dictJson and arrayJson
- Delete all deprecated features
- Add letops support HOT 1
- Add odoc comments
- Change the implementation of optional
- optionalField produces wrong error on non-object JSON HOT 1
- Int decoders succeed on out-of-range numbers
- Order of `fallback` arguments should be switched
- Needs bs-abstract upgrade HOT 4
- mention bs-bastet as a peer dependency over bs-abstract in the docs HOT 2
- decoding-variants#complex-variants HOT 3
- bs-decode no longer compiles v0.11.1 HOT 2
- Production users, roadmap? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from bs-decode.