New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add curried functions #37
Conversation
This looks good, the JSVerify environment is pretty nice :) Can you move the curried functions to the const warnDeprecation = require('folktale/helpers/warnDeprecation');
const deprecatedFL = (name, result) =>{
warnDeprecation(`Type.${name}() is being deprecated in favour of Type['fantasy-land/${name}']().
Your data structure is using the old-style fantasy-land methods, and these won't be supported in Folktale 3`);
return result;
}
const map = (fn) => (type) =>
type['fantasy-land/map'] ? type['fantasy-land/map'](fn)
: deprecatedFL('map', type.map(fn)) EDIT: I forgot to mention, but swapping the argument order for concat/equals/etc is a good idea (though it doesn't matter for equals). I've documented all the types here: https://github.com/origamitower/folktale/blob/master/ROADMAP.hs#L173-L234, but feel free to suggest something different if you think it's more useful :) |
OK, I am also seeing that there are more functions to be implemented. |
Updated the environment to feature other types. Added 'equals' and 'bimap' Moved the module to fantasy-land/curried
Added |
I added the deprecation warnings. Note that we are using an old version of fantasy-land, that does not support I reviewed the typedocs. On |
I think we can use |
Ah, as for the method names, the idea is to just use the literals instead of depending on the const bimap = 'fantasy-land/bimap';
module.exports = (f, g) => (a) =>
typeof a[bimap] === 'function' ? a[bimap](f, g)
typeof a.bimap === 'function' ? a.bimap(f, g)
: /*otherwise*/ unsupported(a); The |
Using I think defining the curried functions manually may prevent some errors, that may occur in cases when two or more arguments always go together, like in Just to be clear, what you want is
|
Out of curiosity, why do you want to avoid depending on Fantasy Land for the method names? |
Maybe because of FL's dependencies |
@boris-marinov yup, pretty much that. As for the dependency in the Since most implementations don't use the library (the old Folktale modules don't, for example) you have to account for all different versions of the fantasy-land spec anyway, and the The other problem is that we place the burden on the user to decide which version of the fantasy-land module to pick, since it can't be installed as a regular dependency. So, mostly I don't see the advantage in bringing that dependency when spec changes are not frequent, and we'd want to support older specs in any case. edit: (also, the |
True. The best bet is to have an (implicit) peer dependency on one hand and default values in case the peer dependency is not defined, on another. SO says that we can do:
but I haven't tested it. Also, since we use the method names in at least two occasions (at the place where each type is defined and in Otherwise I refactored the FL functions to use |
That implicit peer dependency idea looks nice 👍 |
Using We can have a helper module exporting those. // helpers/fantasy-land.js
module.exports = {
equals: 'fantasy-land/equals',
concat: 'fantasy-land/concat',
empty: 'fantasy-land/empty',
map: 'fantasy-land/map',
ap: 'fantasy-land/ap',
of: 'fantasy-land/of',
reduce: 'fantasy-land/reduce',
traverse: 'fantasy-land/traverse',
chain: 'fantasy-land/chain',
chainRec: 'fantasy-land/chainRec',
extend: 'fantasy-land/extend',
extract: 'fantasy-land/extract',
bimap: 'fantasy-land/bimap',
promap: 'fantasy-land/promap'
} // core/fantasy-land/ap.js
const { ap } = require('folktale/helpers/fantasy-land');
module.exports = (a, b) =>
... |
It will also enable us to use the Fantasy Land lib later, if appropriate. |
Thankies :) |
This is Part I of the
control.monad
package because it became somewhat big (and because I am very late).The PR includes all functions from the curried.js file of the prev library where:
concat
function were not in the correct order in the original lib, so instead of(a) => (b) => a.concat(b);
, it should be(b) => (a) => a.concat(b);
(in the same way thatmap
is(f, a)=>...
). What do you think?The PR also includes:
Maybe
datatype.This one, is very fresh but it seems to work perfectly. So for example if you have the
test/environment.es6
underenv
, you can write:and
mf
will be a function that accepts a JSON value and returns a folktale monad (data.either
ordata.maybe
) that contains a JSON value.ma
will be a JSON value contained in the same monad.As usual all comments are welcome!