npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@leading-works/result

v0.0.6

Published

success or failure

Downloads

5

Readme

Result Monad Typescript Implementation

Usage

Use Result as way to encapsulate the result of an operation that can either succeed or fail:

type Car = any // something useful
const cars<Result<Car[]>> = service.getData(); // some async function

// some middleware transformations
const processedCars: Result<Car[]> = service.toViewModel(cars)

// frontend
if (processedCars.isFailure()) {
  // inform about the error
  return <Error message={processedCars.getReasons()} />
} else {
  return processedCars.join().map(car => <CarView car={car} />)
}

References

See:

  • https://pragprog.com/titles/swdddf/domain-modeling-made-functional/
  • https://adambennett.dev/2020/05/the-result-monad/
  • https://csharp-functional.readthedocs.io/en/latest/result-monad.html

Raison d'être

The Result Monad shall abstract the concept of an operation that can either succeed or fail. Should the operation succeed, it returns a Success construct with the expected data. Should the operation fail, it will contain a Failure structure with a List of relevant data (e.g. a list of error messages or a list of Error objects with a Status Code, a Detailed Message and a Simple Message).

The idea is to provide a Structure that may abstract away Success and Failure, and provide a useful List of Reasons when the operation has failed. The solution shall offer developers and integrators the possibility to distinguish detailed Technical Reasons with simpler Messages for Hu-mans with an optional Status code or Error code. This possibility shall give Frontend developers the possibility to avoid leaking information on their GUI, yet give end users enough information to obtain sufficient support when needed. An application architect may centralize logs with some reconciliation IDs in that effect, or maintain a table of technical errors with a table of Error IDs for the end users.

With this idea in mind, the List of Reasons encapsulated in the Failure structure shall be generic, so that integrators can craft the Reason data structure however they like.

API

The Result Monad shall source its inspiration from the Maybe Monad and the Either Monad.

A Result Typescript Choice can either be a Success of T, or a Failure of Reason. Both structure offer the same API, as does the Just and Nothing types: they implement the same type class.

Convenience method will be added so that the Monad is easily usable in the Typescript / JavaScript world. When other languages uses different method name (e.g. chain, bind, etc.), we will alias these names so that developers may use the semantics they are comfortable with.

In order to be a Monad, the Result Monad will implement the Functor type class, the Applicative type class and the Monad type class.

Pointed Functor type class

In order to be a Pointed Functor, the construct must implement of(...) and map(...), where:

of :: (a) -> f a
fmap :: (a -> b) -> f a -> f b

Laws

It must also honour theses laws:

  • the identity law: fmap id = id;
  • the associativity law: fmap (g . f) = fmap g . fmap f.

Applicative Functor type class

In order to be an Applicative Functor, the construct must implement ap(...), where:

pure :: a -> f a
ap :: f (a -> b) -> f a -> f b

Laws

It must also honour theses laws:

  • the identity law: pure id <*> v = v;
  • the homomorphism law: pure f <*> pure x = pure (f x);
  • the interchange law: u <*> pure y = pure ($ y) <*> u
  • the composition law: pure (.) <*> u <*> v <*> w = u <*> (v <*> w).

Every Applicative Functor is also a Functor, map/fmap can be written in terms of ap:

fmap g x = pure g <*> x

Monad type class

In order to be a Monad, the construct must implement return(...) and chain(...)(akabind(...)`), where:

return :: a -> m a
chain :: m a -> (a -> m b) -> m b

Laws

It must also honour these laws:

  • the left identity law: unit(x) >>= f === f(x);
  • the right identity law: ma >>= unit === ma;
  • the associativity law: ma >>= λx -> (f(x) >>= g) === (ma >>= f) >>= g.