foldCase / mapCase
Function that are only invoked when type is in a specific case.
mapCase
is like map but you specify which case is Right/Just etc
foldCase
is like mapCase
but returns the raw value from the visitor, accepts a required otherwise value.
Related #5 (closed)
Considerations
Do we pass in a string for the name of the case, or a reference to the case itself?
I'd prefer the former, but according to the spec the "case" is nothing but a key on the type, there's no requirement for it to have e.g. a name
property, so there'd be no way for mapCase
or foldCase
to reliably no which case is being passed in without also passing the the type itself, which would be cumbersome.
That said, not passing in the type, may not even be an option because we want type checks on this function.
Even if we pass in the type (which I now think we need to do), looping over the types cases and doing equality checks is not within the spirit of the library (serializable). So maybe the spec should change and a type's case has to have a name
property.
const Loaded = {
Y: { name: 'Y' },
N: { name: 'N' },
name: 'Loaded'
}
I think that's reasonable and doesn't break existing usecases like e.g.
const Loaded = {
name: 'Loaded',
Y(){
...
},
N(){
...
}
}
or
function Loaded(){
}
Loaded.Y = function Y(){ ... }
Loaded.N = function N(){ ... }
or
class Loaded {
static Y(){ ... }
static N(){ ... }
}
Examples
const Loaded = yslashn.maybe('Loaded')
const f = mapCase (Loaded) ( Loaded.Y ) ( x => x.toUpperCase() )
f( Loaded.Y( 'hello' ) )
//=> Loaded.Y ('HELLO')
const Loaded = yslashn.maybe('Loaded')
const f = foldCase (Loaded) ( Loaded.Y ) ('') ( x => x.toUpperCase() )
f( Loaded.Y( 'hello' ) )
//=> 'HELLO'
f( Loaded.N() ) //=> ''