GithubHelp home page GithubHelp logo

ramda / ramda-fantasy Goto Github PK

View Code? Open in Web Editor NEW
1.5K 1.5K 95.0 213 KB

:ram::sparkles: Fantasy-Land compatible types for easy integration with Ramda.js

License: MIT License

JavaScript 100.00%

ramda-fantasy's People

Contributors

avaq avatar buzzdecafe avatar crosseye avatar customcommander avatar davidchambers avatar gilligan avatar henryqdineen avatar idcmardelplata avatar jairovsky avatar jimf avatar jonboiser avatar joneshf avatar koleok avatar kujon avatar legomushroom avatar mickdekkers avatar mujuni88 avatar raine avatar rpominov avatar safareli avatar scott-christopher avatar stoeffel avatar theludd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ramda-fantasy's Issues

Some examples?

Please, some examples of use of these cuties, thanks.

Bower

Would be nice to download this using bower

Get this party started?

Hello @CrossEye @buzzdecafe @davidchambers!
I don't know what the plan for ramda-fantasy is but recently I have begun using monads in my programming and since I love ramda I would also love for the ramda community to maintain its own type library unless the maintainers of ramda think that there are better alternatives out there in the wild.

Looking at this repo, what I initially see is missing is:

  • Tests
  • Build system
  • Code cleanup
  • Code documentation
  • Website

I am of course willing to help our here, to contribute and learn more about how to do functional programming right. I am curious what the rest of the people invested in ramda thinks.

Maybe and Either have different "commute" semantics

Commuting a list of Maybes results in a Nothing if any of the elements if a Nothing:

> R.commute(Maybe.of, [Maybe.Just(1), Maybe.Just(2)])
Maybe.Just([1, 2])
> R.commute(Maybe.of, [Maybe.Just(1), Maybe.Just(2), Maybe.Nothing()])
Maybe.Nothing()

Commuting a list of Eithers results in a Right whose value is a list containing each Right's value:

> R.commute(Either.of, [Either.Right(1), Either.Right(2)])
Either.Right([1, 2])
> R.commute(Either.of, [Either.Right(1), Either.Right(2), Either.Left('XXX')])
Either.Right([1, 2])

Reader ask

Should Reader.ask equal Reader(R.identity) ? so the following would work

const append = str => Reader.ask.map((strToo) => str.concat(' ', strToo));
const greet = R.compose(R.chain(append), Reader.of);
greet('hello').run('world'); //=> hello world

rather current with Reader.ask = Reader(R.always)

const append = str => Reader.ask.map((strToo) => str.concat(' ', strToo()));
const greet = R.compose(R.chain(append), Reader.of);
greet('hello').run('world');  //=> hello world

you need to call strToo()...

Maybe as a Semigroup?

Hello!

Firstly, this project is great, and I've been playing with it for a few weeks. I have to ask, though: is there a reason why Maybe doesn't have a concat method defined? As I see it, the concatenation would work like this:

Nothing `concat` Nothing = Nothing
Nothing `concat` x = x
x `concat` Nothing = x
(Just x) `concat` (Just y) = Just (x `concat` y)

I'm more than happy to submit the PR if this sounds reasonable - just thought I'd double check in case I'd missed something obvious :)

Release to npm?

Could that be done?

I think the version should be changed to something low, like 0.1.0 but I would really like it to be on npm just so that it will be easy to install to other projects for trying out. We could also update the readme to disclaim that this is pre alpha or what we would like to call it and that the API is running a high risk of being changed in this phase.

Discussion: Support toMaybe for Maybe Monad

I miss good way to wrap nullable values in the Maybe Monad.
Option Types nowadays usually provide a static constructor ofNullable, which returns Just(x) or Nothing() depending on the value given.
I don't want to use Maybe(x) directly, since I want to show more explicitly that my wrapped value is nullable.
I could implement ofNullable if there is an agreement to support this.

Proposal: Pair & Tuple functor

Background

This started as issue 1048 at the ramda repository. I'm working with 2-dimensional arrays where the nested arrays are all length-2, I've imagined them as being tuple pairs. My first needs were the fst and snd functions in Ramda to handle those pairs. Later we talked about creating a Pair or Tuple functor, which might be more useful in general.

I've fooled around a bit in this Gist, however I'm not satisfied with the results so far. (Is my use of .of() correct? Do I understand the Applicative specification at all?)

But lets first answer: what should the API be?

API Examples

Given an array:

var pair1 = Pair(['one', 2]);
fst(pair1); //=> 'one'
snd(pair1); //=> 2

Given 2 arguments:

var pair2 = Pair('one', 2);
fst(pair2); //=> 'one'
snd(pair2); //=> 2

Creating instances with Pair.of():

var text = ['one', 'two', 'three'], numbers = [1, 2, 3];
R.map(Pair.of, R.zip(text, numbers)); //=> [Pair, Pair, Pair]

Implementation

@DrBoolean suggested an array-friendly solution, which plays nice with R.nth() and R.head():

var _Tuple = function(x, y) {
  this[0] = x;
  this[1] = y;
  this.length = 2;
}

As a last remark, I personally don't think I'm qualified, since my functional programming on the level of algebraic structures is afaik not good enough. I've started learning Haskell but I'm mainly still figuring things out. I would love to help out, but don't let me slow you down.

Basic Future example

I've been unable to get the most basic example of a working Future to work. I would suggest updating the documentation with a simple working version of a Future that returns a value.

Future.of((reject, resolve) => {
  setTimeout(() => resolve('success'), 500)
}).fork(console.error, console.log)
// log: 'success'
// output: undefined

If fork is necessary to evaluate a Future, but fork can only return undefined, how is it possible to unwrap the computed value?

new release

its been a while since an NPM version was released.
Right now I have a projected pointed directly at github, and I'm getting flak for it, would you guys be able to release a new version?

name change?

from this comment: ramda/ramda#1638 (comment)

anyone have strong feelings one way or the other on the name ramda-fantasy? Possible alternatives (in no particular order) include:

  • ramda-types
  • algebramda
  • ramdalgebra
  • ???

BUG: Maybe monad evaluated to 'Just { value: undefined }'

E.g. give me the string after the question-mark. So if we do NOT have a
question-mark, we expect the Maybe monad to handle the undefined gracefully.
But following test fails:

    expect(R.compose(
      R.map(R.nth(1)),
      R.map(R.split('?')))(Maybe('')))
    .toEqual(Maybe.Nothing())

We get something like:

  Error: Expected { value: undefined } to equal {}
  + expected - actual

  -{
  -  "value": [undefined]
  -}
  +{}
So the map-method of Maybe should not use this.of(x) but Maybe(x) instead.

Release 0.4.0

Are we good with releasing current master as 0.4.0?

shouldn't Left have a map?

Shouldn't Left have a map that returns self?
If I have an Either and I call map on it, I want it to Either do the mapping or if it's a Left than return the Either with the left in it. Don't I?
Thanks,
R

_nothing may leak, get mutated

var n = Maybe.Nothing();
n.x = "mutated";
Maybe.Nothing().x; // "mutated"

this seems bad. I think we should rethink how Nothing is implemented. It relies too much upon the good behavior of the developer.

Lift and IO

Moved from ramda/ramda#677

@donnut reported:

In v0.7.0 the following (simplified) snipped worked fine.

    var io1 = IO.of(2);
    var io2 = IO.of(5);
    R.lift(function(a, b) { return a + b;}, io1, io2).runIO(); // => 7

In v0.8.0 it throws an error because R.lift returns an empty array instead of a IO instance. I took a quick look at the differences between the two versions, but I can find any reason why lift stopped doing what it did previously.

Note: It is amazing how much work you guys have done in a couple of weeks!

Disconnect notion of failure from future

Straight out of #70 (comment) but contiuing the discussion here:

I find this very interesting. It has bothered me that there are two ways of handling errors, Future and Either. What would be gained from removing the forking from futures and replacing it with run or something similar?

"Abstract" types

From the fantasy-land Monad specification.

A value which satisfies the specification of a Monad does not need to implement:

  • Apply's ap; derivable as function(m) { return this.chain(function(f) { return m.map(f); }); }
  • Functor's map; derivable as function(f) { var m = this; return m.chain(function(a) { return m.of(f(a)); })}

This could mean that we could create this type:

function Monad() {}
Monad.prototype.ap = function(m) { return this.chain(function(f) { return m.map(f); }); }
Monad.prototype.map = function(f) { var m = this; return m.chain(function(a) { return m.of(f(a)); })}

.. and then implement stuff like

function Maybe() {};
inherits(Maybe, Monad);

function Just() {};
inherits(Just, Maybe);

Just.prototype.of = ...
Just.prototype.chain = ...

This also removes the need to test if the type has all the monadic functions. All that is required is to assert it is an instance of Monad.

There are also other examples of functions that can be derived from other types.
Good/bad idea?

IO tests fail with ramda 0.17

I was trying to upgrade to ramda 0.17.x but the tests for IO fail. I can't really see why. Does anyone else have an idea?

needs UMD wrapper

I am transpiling my es6 to AMD modules with Babel. I may take a shot at putting this lib in the UMD wrapper so it will work with both flavors of modules.

Maybe#map

Hey there.

In Chapter 8 in @DrBoolean's book, it is told about Maybe:

Maybe.of({
  name: 'Boris',
}).map(_.prop('age')).map(add(10));
//=> Maybe(null)

yet when I execute it with ramda-fantasy i get:

image

Should it be this way? is it a bug? Isn't Maybe checks nulls every time?

Take Sanctuary

Should we merge RF and Sanctuary?
What would a merger of RF an Sanctuary look like?

Having problems with composeK docs example

The problem could be ignorance on my part. I occasionally use the docs to familiarize myself with new concepts and I was just looking over the docs for composeK and attempted to try out the example in the REPL.

I understand that there are trade offs between succinct examples and providing clarity for users new to FP. I was comfortable filling out the missing parseJson and get functions and even looking up Sanctuary to understand Maybe. Even after having done that though there are still several things that I don't understand about the example and I'm wondering if it's a lack of understanding on my own part of something wrong with the example, Ramda or Sanctuary.

Here is my code (http://goo.gl/4aCLE4):

//  parseJson :: String -> Maybe *
// this should work :
//var parseJson = S.encase(JSON.parse);
// but does not, it throws a type error.
// instead you have to unwrap the maybe and rewrap it?
var parseJson = str => {
  var result = S.encase(JSON.parse, str)
  return Maybe.of(result.value);
}
//  get :: String -> Object -> Maybe *
var get = str => obj => {
  return Maybe.of(obj[str]);
}

var getStateCode = R.composeK(
  R.compose(Maybe.of, toUpper),
  get('state'),
  get('address'),
  get('user'),
  parseJson
);

getStateCode(Maybe.of('{"user":{"address":{"state":"ny"}}}'));
//=> Just('NY')
//getStateCode(Maybe.of('[INVALID JSON]'));
//=> Nothing()

Two primary questions:

  1. Why does the commented out parseJson implementation throw a type error? S.encase is curried by default and returns a Maybe but the error message seems to indicate that it is not of type Maybe b?
  2. The example in the docs makes use of Maybe.of but it seems that S.toMaybe is better since it handles undefined being Nothing. I've had several attempts on the invalid JSON where the composition, R.compose(Maybe.of, toUpper) failed because toUpperCase is not a function on undefined. The code seems to be written with the assumption that undefined would be Nothing and therefore not have the chain method invoked. Is that correct?

Thanks to anyone who can provide insight :).

Future.finally

Should there be an equivalence of a finally statement on futures? I recently used that with promises and I wondered how I would solve the same situation with futures. Folktale has a cleanup method but it is supplied with the constructor. To me that seems a bit weird. Should it not be called together with fork?

Thoughts?

Maybe

wouldn't you want to implement the Maybe constructor and the Maybe.of method like this:

function Maybe( x ) {
    return ( x === null || x === undefined ) ? _nothing : Maybe.Just( x );
}

Maybe.of = function( x ) {
    return new Maybe( x );
}

Currently if I do something like this

Maybe.of( undefined );

I get back a _Just {value: undefined}

Bower reference Ramda versioning

The package.json shows a version range up to 0.20 but bower.json is fixed at 0.14. ?
Is there a particular reason holding back the dependency for bower RF to be in line with 0.19.x Ramda?

Unable to find a suitable version for ramda, please choose one:
    1) ramda#^0.14.0 which resolved to 0.14.0 and is required by ramda-fantasy#0.4.1
    2) ramda#^0.19.1 which resolved to 0.19.1 and is required by my-project

Cheers

Maybe toString gives away internals

No big deal, but perhaps worth raising here.

Noticed the toString on Maybe is displaying _Just rather than Just. Haven't checked other Types to see if they exhibit the same behaviour. It would be cleaner if it returned a toString of what the user is workiing with - Just and Nothing in this case.

const nestedIceCream = Maybe(Maybe('Ice cream'));
console.log(nestedIceCream);
// _Just { value: _Just { value: 'Ice cream' } }

Thoughts?

Don't catch errors in resolve fns, chains, etc...

Unnecessary error catching is something that, IMO, we should avoid in Future/Task implementations. e.g.

function createFuture() {
  return new Future(function computation(reject, resolve){
    setTimeout(() => {
      resolve('hello');
    }, 0);
  });
}

createFuture().fork(
  left => { console.log('left', left.message); },
  right => { console.log('right', right); throw new Error('boom'); }
);

This example will log in the console:
right hello
left boom

This is not good as it's completing the future twice and mixing rejections with unexpected errors (something that Promises do). If there is code that might be prone to throwing an error (such as JSON.parse or accessing nested props in an object) THAT code should get wrapped in a try/catch. The Future/Task should have no opinion on error catching.

Utility functions of varying purity

I did some experimentation today and hacked together futurify and futurifyAll functions inspired by bluebirds promisify and promisifyAll.

I was wondering if this is of interest for ramda fantasy. Would they be something that we would want to put in this project, a separate utility-project or not in ramda at all?

Either.either not in latest release

I was wondering if this is an issue or not, but the documentation shows the use of Either.either but this method is not included in the latest release (0.4.1) even though the commit for this addition is from 2015, I'm just wondering if you could add this to the release because I downloaded via NPM and trying to use it found out it is not available in the latest tagged release only in the master.

Tuple Applicative Behaviour

As briefly discussed on Gitter, the current Applicative implementation for Tuple doesn't behave.

Tuple.of(R.identity).ap(Tuple.of({}));
//=> [TypeError: function f1(a) { ... } be a semigroup to perform this operation]

I currently see three options here:

  • (1) Downgrade Tuple to Apply by dropping of.
  • (2) Change the current ap implementation to:
_Tuple.prototype.ap = function(m) {
  return Tuple(this[0](m[0]), this[1](m[1]));
};
  • (3) Change the current of implementation to something like:
Tuple.of = function(x) {
  return Tuple({ concat: R.identity }, x);
};

I think I'd like to see Tuple take on option 2 and if desirable, introducing a Writer type that can implement option 3, but I'm keen to hear the thoughts of others.

consider using sanctuary-def to avoid ad hoc type checking

In #88, for example, we're adding:

Maybe.isJust = function(x) {
  if (typeof x.isJust !== 'function') {
    throw new TypeError('invalid type given to Maybe.isJust');
  } else {
    return x.isJust();
  }
};

With sanctuary-def, we could write:

//  Maybe.isJust :: Maybe a -> Boolean
Maybe.isJust =
def('Maybe.isJust',
    {},
    [$Maybe(a), $.Boolean],
    function(maybe) { return maybe.isJust(); });

Docs and site

I think that this library is quite useful in its current state but the impression is not that good when looking at the code. One reason is the lack of documentation and structure. I have never used jsdoc myself (other than to write it in working environments). Is there anyone with knowledge that knows what it will take to generate documentation? I think that a site with published documentation would greatly improve the status of this project.

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.