GithubHelp home page GithubHelp logo

seidr's Introduction

Seidr

In Old Norse, seiðr was a type of sorcery practiced in Norse society during the Late Scandinavian Iron Age. The practice of seiðr is believed to be a form of magic relating to both the telling and shaping of the future.

A collection of general purpose Sum Types and monads built on top of hojberg/sums-up

Maybe

import { Just, Nothing } from 'seidr';

Just("Loki").caseOf({
  Nothing: () => "N/A",
  Just: name => `Hello ${name}`,
}); // => "Hello Loki"

Nothing().caseOf({
  Nothing: () => "N/A",
  Just: name => `Hello ${name}`,
}); // => "N/A"

// Map doesn't run on Nothing
Just("Loki").map(name => name.toUpperCase()); // => Just("LOKI")
Nothing().map(name => name.toUpperCase()); // => Nothing()


// flatMap unnests a layer when the mapper returns a Maybe
Just("Loki").flatMap(name => Just(name.toUpperCase())); // => Just("LOKI")
Nothing().flatMap(name => Just(name.toUpperCase())); // => Nothing()

Result

import { Ok, Err } from 'seidr';

Ok("Loki").caseOf({
  Err: err => err,
  Ok: name => `Hello ${name}`,
}); // => "Hello Loki"

Err("oops").caseOf({
  Err: err => err
  Just: (name) => `Hello ${name}`,
}); // => "oops"

// Map doesn't run on Err
Ok("Loki").map(name => name.toUpperCase()); // => Just("LOKI")
Err("oops").map(name => name.toUpperCase()); // => Err("oops")

// flatMap unnests a layer when the mapper returns a Result
Ok("Loki").flatMap(name => Ok(name.toUpperCase())); // => Ok("LOKI")
Err("oops").flatMap(name => Ok(name.toUpperCase())); // => Err("oops")

// Result and Maybe are not isomorphic as "oops" is lost when converting Err to Nothing
Ok("Loki").toMaybe(); // => Just("Loki")
Err("oops").toMaybe(); // => Nothing()

AsyncResult

An AsyncResult<L, R> is a hybrid of a Result<L, R> and a Promise<R>, with the type safety and convenience methods of the former, but the ability to capture a not-necessarily-evaluated-yet value of the latter.

An AsyncResult<L, R> can be constructed from a Promise<R> with an appropriate function to convert the promise's unknown error value to an L.

There are also AsyncOk and AsyncErr functions available as shorthand, though in practice these are less frequently useful.

import { AsyncResult, AsyncOk, AsyncErr } from 'seidr';

////////////////////////////////////
// Constructing an AsyncResult

const myPromise: Promise<{ name: string }> = /* ... */;

AsyncResult.fromPromise(err => new Error(String(err)), myPromise);
// => AsyncResult<Error, { name: string }>


////////////////////////////////////
// Using an AsyncResult

// `caseOf` always returns a promise
AsyncOk("Loki").caseOf({
  Err: err => err,
  Ok: name => `Hello ${name}`,
}); // => Promise { <resolved>: "Hello Loki" }

AsyncErr("oops").caseOf({
  Err: err => err,
  Ok: (name) => `Hello ${name}`,
}); // => Promise { <resolved>: "oops" }

// `map` doesn't run on Err
AsyncOk("Loki").map(name => name.toUpperCase());  // => AsyncOk("LOKI")
AsyncErr("oops").map(name => name.toUpperCase()); // => AsyncErr("oops")

// `flatMap` unnests a layer when the mapper returns a Result, AsyncResult or Promise<Result>
AsyncOk("Loki").flatMap(name => Ok(name.toUpperCase()));       // => AsyncOk("LOKI")
AsyncOk("Loki").flatMap(name => AsyncOk(name.toUpperCase()));  // => AsyncOk("LOKI")
AsyncOk("Loki").flatMap(async name => Ok(name.toUpperCase())); // => AsyncOk("LOKI")
AsyncErr("oops").flatMap(name => Ok(name.toUpperCase()));      // => AsyncErr("oops")

// `toPromise` returns promise that resolves on Ok or rejects on Err
// A `Promise<R>` and an `AsyncResult<L, R>` are isomorphic at runtime,
// as the error value isn't lost; only the type information is.
AsyncOk("Loki").toPromise();  // Promise { <resolved>: "Loki" }
AsyncErr("oops").toPromise(); // Promise { <rejected>: "oops" }

Effect

import { Effect } from 'seidr';

const fooEff = Effect(() => "foo") // Effect("foo")

fooEff.unsafePerform() // => 'foo'

// Map doesn't run on Err
fooEff.map(val => val.toUpperCase()); // => Effect("FOO")

// flatMap unnests a layer when the mapper returns an Effect
fooEffect.flatMap(val => Effect(() => val + 'bar'); // => Effect("foobar")

RemoteData

A sums-up implementation of the original pattern described by Kris Jenkins: http://blog.jenkster.com/2016/06/how-elm-slays-a-ui-antipattern.html

This is a helpful sum type for modelling data being fetched from the network.

type RemoteData<E, A> = NotAsked | Loading | Failure<E> | Success<A>
import { RemoteData, NotAsked, Loading, Failure, Success } from 'seidr';

NotAsked().caseOf({
  NotAsked: () => "not asked",
  _: () => "everything else",
}); // => "not asked"

Loading().caseOf({
  Loading: () => "loading",
  _: () => "everything else",
}); // => "loading"

Failure("oops").caseOf({
  Failure: err => err
  _: () => "everything else",
}); // => "oops"

Success("Yay").caseOf({
  Success: data => data
  _: () => "everything else",
}); // => "yay"

// Map only runs on Success
Succecss("Loki").map(name => name.toUpperCase()); // => Just("LOKI")
Failure("oops").map(name => name.toUpperCase()); // => Failure("oops")
Loading().map(name => name.toUpperCase()); // => Loading()
NotAsked().map(name => name.toUpperCase()); // => NotAsked()

// flatMap unnests a layer when the mapper returns a Result when run on Success
Succecss("Loki").map(name => Success(name.toUpperCase())); // => Just("LOKI")
Failure("oops").map(name => Success(name.toUpperCase())); // => Failure("oops")
Loading().map(name => Success(name.toUpperCase())); // => Loading()
NotAsked().map(name => Success(name.toUpperCase())); // => NotAsked()

seidr's People

Contributors

hojberg avatar dadleyy avatar dfreeman avatar adamedgett avatar dependabot[bot] avatar rotondozer avatar skermes avatar

Stargazers

Andrey avatar Kevin Elliott avatar Mathias Schreck avatar João Glória avatar Tim Kersey avatar  avatar Michael Guymon avatar Adrian avatar Juri Hahn avatar  avatar

Watchers

 avatar Adrian avatar James Cloos avatar

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.