Giter VIP home page Giter VIP logo

Comments (6)

andywhite37 avatar andywhite37 commented on August 26, 2024 1

@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.

mlms13 avatar mlms13 commented on August 26, 2024

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.

mrmurphy avatar mrmurphy commented on August 26, 2024

Wow, you guys have done a whole stinking' lot of work on that library. Way to go!

from bs-decode.

mrmurphy avatar mrmurphy commented on August 26, 2024

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.

andywhite37 avatar andywhite37 commented on August 26, 2024

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.

mlms13 avatar mlms13 commented on August 26, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.