Folktale 2.3

15 August 2018

Folktale 2.3 is officially released~ 🎉🎉🎉

You can now install it as the latest release:

npm install folktale

You can upgrade by specifying the version:

npm install folktale@2.3.0

Not a very exciting release as it mostly just cleans up a few things. But it does promote the Future, Conversions, Lambda, Fantasy-Land, Result, and Validation APIs to stable at last. Tasks are still in need of some love before they can reach that status, although hopefully most of the edge cases in the API have been fixed now.

This release improves the error reporting in the ADT APIs as well. Previously if you forgot to provide one of the cases to an union’s matchWith method, you’d get this very unhelpful message:

const { union } = require('folktale@2.1.0/adt/union');
const Optional = union('optional', {
  Some(value) { return { value } },
  None() { return {} }
});

function getValue(optional) {
  return optional.matchWith({
    Some(value) { return value }
  });
}

getValue(Optional.Some(1));  // => 1
getValue(Optional.None());   // => TypeError: pattern[name] is not a function

In Folktale 2.3 you get a more descriptive error message:

Error: Variant "None" is not covered in pattern.
This could mean you did not include all variants in 
your Union's matchWith function.

For example, if you had this Union:

const Operation = union({
  Add: (a, b) => ({ a, b }),
  Subtract: (a, b) => ({ a, b }),
})

But wrote this matchWith:

op.matchWith({
  Add: ({ a, b }) => a + b
  // Subtract not implemented!
})

It would throw this error because we need to check against 'Subtract'. 
Check your matchWith function's argument, it's possibly missing the 
'None' method in the object you've passed.

We also support a “match anything” special value now. So another way of writing the getValue function above that would be more practical for unions with many cases would be:

const { union } = require('folktale/adt/union');

const Optional = union('optional', {
  Some(value) { return { value } },
  None() { return {} }
});

function getValue(optional) {
  return optional.matchWith({
    Some(value) { return value },
    [union.any]() { return null }
  });
}

getValue(Optional.Some(1));  // => 1
getValue(Optional.None());   // => null

Check out the changelog for all the changes

Acknowledgements

As always, a huge thank you to everyone who contributed to improving Folktale, by reporting errors, sending feedback, talking about it, sending patches, etc.

This release wouldn’t be possible without the contributions of @Josh-Miller, @JesterXL, @andys8, and @pernas. Really, thank you :>