monet / monet.js

monet.js - Monadic types library for JavaScript
https://monet.github.io/monet.js/
MIT License
1.6k stars 114 forks source link

How to supply a `Semigroup appender` to `sequenceValidation`? #237

Open jdwolk opened 3 years ago

jdwolk commented 3 years ago

Hi!

I'm using Validation and I noticed most of the examples in https://github.com/monet/monet.js/blob/master/docs/VALIDATION.md use strings as the data structure on the Fail side. I want to supply a richer data structure but so far I'm coming up short.

I know that the parameterized type on the side of Fail needs to be a semigroup so that values can be "rolled up" with the equivalent of mconcat (I think?). So the error message I'm getting (Couldn't find a semigroup appender in the environment, please specify your own append function) does make sense to me. I'm just not sure how to go about creating the data structure + operations to make them compliant w/ this lib so I can use them.

Here's my code:

import * as R from 'ramda';
import { Validation, List } from 'monet';
const { Success, Fail } = Validation;

const isNonNullString = (str) => {
  return R.contains('null', str) ?
         Fail({ val: str, message: `'${str}' contained null`}) :
         Success(str)
}

/* NOTE: ^ CAN work with the following:

Fail([{ val: str, message: `'${str}' contained null`}])

since array is already a supported semigroup (I think?)
*/

const testStr1 = 'hello'
const testStr2 = 'hinullthere'
const testStr3 = 'boomnullalso'

const check = (str) => Success(str).chain(isNonNullString)

const testStrs = [
  testStr1,
  testStr2,
  testStr3,
];

const allTests = List.fromArray(R.map(check, testStrs)).sequenceValidation()
console.log('All tests: ', allTests);

Assuming I don't want my return type to be a known semigroup like string or array: how would I make one + supply it to sequenceValidation (or sequence?) to avoid getting this error?