Code Monkey home page Code Monkey logo

fantasy-land's People

Contributors

5outh avatar avaq avatar bergus avatar branneman avatar chicoxyzzy avatar dakom avatar davidchambers avatar fl4m3ph03n1x avatar frankshearar avatar gabejohnson avatar gigobyte avatar gitter-badger avatar joneshf avatar kennknowles avatar kiaragrouwstra avatar mudge avatar nsluss avatar oncicaradupopovici avatar phadej avatar puffnfresh avatar raynos avatar rjmk avatar robotlolita avatar rpominov avatar safareli avatar scostello avatar scott-christopher avatar sdwebster avatar simonrichardson 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  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

fantasy-land's Issues

Add Applicative

Provides a ap and of methods. Monad inherits from Applicative and derives ap as a.chain(function(f) { return b.map(f); }).

Quick translation of the laws. Will need some checking:

  • a.of(function(a) { return a; }).ap(v) is equivalent to v (identity)
  • a.of(function(f) { return function(g) { return function(x) { return f(g(x))}; }; }).ap(u).ap(v).ap(w) is equivalent to u.ap(v.ap(w)) (composition)
  • a.of(f).ap(a.of(x)) is equivalent to a.of(f(x)) (homomorphism)
  • u.ap(a.of(y)) is equivalent to a.of(function(f) { return f(y); }).ap(u) (interchange)

Why can `of` be defined on the constructor?

It's quite possible that I'm simply missing something simple, but I'm disturbed by this sentence (emphasis added):

A value which has an Applicative must provide an of method on itself or its constructor object.

(All the same points will apply to Monoid's empty method, but it's Applicatives which are worrying me now.)

For a specification which is usually so prescriptive, this is surprisingly lax. But that's not the real problem. It seems to me that this makes it tremendously more difficult to write code that works across all Applicative Types; in fact, it probably makes it impossible.

A few points:

  • First of all, the Applicative laws, and Monad's left identity are written only in terms of the instance version of of. Should the specification be taken to read, for instance, "The appropriate one of m.of(a).chain(f) or m.constructor.of(a).chain(f) is equivalent to f(a) (left identity)" or some more precise version of the same?
  • It makes unwarranted assumptions about how I create types. In these days of Object.create, why should the specification assume that I use constructor functions to define my types? It's quite possible to do without them, and it's growing ever more popular to work that way.
  • It is possibly incoherent. Since nothing specifies which of the two I must implement, I can choose to implement the same of on both. This would probably not cause an issue. But nothing in the specification would prevent me from creating a conforming of on the instances and an unrelated of on the constructor or vice versa:
    Maybe.of = function(val) {return new Just(val);};
    Maybe.prototype.of = function(val) {throw "Unknown Preposition";};

Does that conform to the specification as written so long as Maybe.of upholds the required laws?

Does this one so long as Maybe.prototype.of upholds the laws?:

    Maybe.of = function(val) {throw "Unknown Preposition";};
    Maybe.prototype.of = function(val) {return new Just(val);};

If so, can anyone suggest a way that I can generically apply of to algebraic types without knowing for each specific type which version is being used?

Or... am I just missing something simple again?

This was all brought to mind by a recent Ramda issue.

"bind"

In the spec it says "A value which has a bind" when defining chain. The word "bind" is not defined or generally ambigious

consider not using then

Promises are not and probably will never be monads.

So consider using something not taken by the promise people to avoid confusion

Comonad

It seems like we're implementing comands in a few of the libraries (Promises, etc) we should update the specification around this. Then we can update the quick check library to allow us to test for this.

Assuming the following:

extend extract      = id
extract . extend f  = f
extend f . extend g = extend (f . extend g)

Add Quickcheck to spec to motivate dev dependency

Over at #68 I had an issue with using Id to express a traversable law - i.e. using an implementation within the spec.

At #66 @phadej suggested we motivate some reason to depend on the spec so we can chart it's use and have a reason for versioning.

I'd like to see a law quickcheck test script included in the spec. Something like: https://github.com/folktale/laws

That would allow people to add fantasy-land as a dev dependency as well as give me a reason to include Id

My vision is something like:

var fl = require('fantasy-land')
fl.quickcheck(MyType, [fl.functor, fl.traversable, fl.foldable]);

I also believe it makes sense to do the derivations from fl, but that might be overboard.

Write a test suite

Needs to test values against the algebraic laws we specify. The best method would be a QuickCheck like framework.

Functions params naming

It was a little confusing to see same as a param to map and chain. May be we sould somehow separate them (fM looks ugly, guess there'r some other options)?

Consider reordering Applicative

Currently Applicative is the only one that is "backwards" from the other algebras, where the ap is working on a function rather than the data. It makes this a bit hard to think of in terms of map or chain. Can we have it where a.ap(f) implies that a is some data, e.g. option, and f is a function?

Thoughts, ideas, complaints?

Question about Applicatives

Hi guys,

I've been implementing FantasyLand in monet.js and I've come a little unstuck with ap().

Unless I've got the wrong end of the stick FantasyLand's ap() demands that the applicative already contains a function and then accepts an applicative with a value.

appWithFunction.ap(appWithValue)

Unfortunately I've followed scalaz & functional java approach which does the opposite.

appWithValue.ap(appWithFunction)

See here for the Maybe example: http://cwmyers.github.io/monet.js/#apmaybefn

Here is an example from FunctionalJava Option:
public final <B> Option<B> apply(Option<F<A,B>> of)

So my question is why has Fantasy Land taken this particular approach to applicative? I'm worried that this would be a large breaking change to the monet library and I'm trying to figure out what the right thing is to do.

Cheers,
Chris

Just an idea: Why not make `LiftN` the requirement for applicatives rather than `ap`?

It seems like in a language like JavaScript where currying isn't the norm (and might not be performant because of a lack of compiler help), it might be more useful to make something more like LiftN the requirement for applicative rather than ap. It could even be backwards compatible for non-library code by just allowing ap to take multiple arguments like this:

MyApp.of(f).ap(a, b, c, d, e)

This would be fairly easy to implement for most applicatives I can think of, and would certainly be more convenient for the user and probably more performant, too.

If this doesn't match the aesthetics of fantasy-land (and my guess is it doesn't), maybe there should be a way for implementors to optionally provide a liftN method (under some friendlier name, maybe just lift) for performance reasons?

Map function is crowded

I think there is a problem with having the functor's map method being called "map". Many other libraries provide implementations of methods called map that are inconsistent.

  • jQuery object's map function takes a function with the signature Number -> Element -> a
  • Array prototype map is a -> Number -> [a] -> b

If the implementation is already there then it is really hard to fix, if it wasn't there at all then we could just add a compliant implementation with the right name. Might it be better if we called the functor's map function something else? Maybe fmap?

I guess that would be an annoying change to make at this point. Maybe implementations could look for an fmap method first and fall-back to map if it doesn't exist?

Error handling ?

There is no notion of error handling in the spec, if wish promises to ever become monadic we should define strategy for error handling.

Create fantasy-land-promise proposal

I think promises/a+ is a lost cause. But DOM Futures is probably not. I thin it would be very useful to have spec outlined and proposed to whoever is working on DOM Futures! I think
the goals of the spec should be:

Define Monad-ic promises that that is backwards compatible with Promise/A. In other words then is de-facto standard and it's too late to change it. But then could be defined by complecting flatMap and some error handling mechanism (see #8)

Semver the spec

I'm starting to see a bunch of projects starting up implementing some version or other of this spec. Since it's changing quite a bit at this early stage, I propose adding a semver version number to allow for clarity of which version of the spec is being implemented.

Name the laws

Each law should be named so it's easier to know what's going on. It's better to say "Law of Associativity" so people can figure out the equivalence.

Why "No parts of b should be checked" for Applicative?

Why is it important for the Applicative of function to not check it's input?

My question arises because I have seen two different types of implementations for Maybe, one that pretty much looks like this where the check to see if the value is null is done in the map function:

function Maybe(val) {
  this.val = val;
};
Maybe.prototype.map = function(f) {
  return this.val == null ? this : new Maybe(f(this.val));
};

and another one which has 2 sub types Just and Nothing.

function Maybe(val) {
  return this.val == null ? new Nothing() : new Just(val);
};

function Just(val) {
  this.val = val;
};

Just.prototype.map = function(f) {
  return new Maybe(f(this.val));
};

function Nothing() {};

Nothing.prototype.map = function(f) {
  return this;
};

My point here is that the second implementation does a check in the constructor, and because of this it would break the fantasy land specification if it implemented of = function(val) return Maybe(val) but this is not true for the first implementation since it does the checking in the map method.

In the second case, Maybe.of can never return something that will not apply the input function in map.

This leads to the situation that because of internal design decisions Maybe.of may be forced to be inconsistent with other implementations in order to fulfill this specification. I find this strange and wonder if I have misunderstood something.

Semigroup

Use concat as the method name. Makes Array compatible.

Why name the Comonad method "from"?

I did like the name extract that was proposed in #57 much more. Why was from chosen?

To me (and probably most other people who don't know what comonads are about), extract is more descriptive and meaningful. Don't we want a self-explanatory spec? It matches the Haskell function as well.

Also, I have some reservations against using from. The term is used in ES6 for static (constructor) methods to assimilate values in a type, e.g. Array.from. Don't we expect some collisions, especially since from originally had a static counterpart (7253b83)?

Sorry for not bringing this up earlier, I seem to have forgotten to watch this repo.

Change the spec so it would require prefixed method names

I propose to change the spec so it would require more unique method names. For example, instead of ap method, a @@fantasy-land/ap. It can be called as foo['@@fantasy-land/ap']().

This would serve two purposes:

  1. It will be easier to add spec support to an existing API, as method names will be guaranteed not taken,
  2. we could use duck-typing to check if an object implements a spec.

This also will allow to create a polyfill that adds fantasy-land support to native JS data structures. It relatively ok to add @@fantasy-land/ap method to Array.prototype, but less ok to add ap.

Also libraries like Bacon, for example, will be able to add fantasy-land support, as for now it problematic with map method, for instance, as it not strictly compatible with the spec, but they could add @@fantasy-land/map that is.

I think this change could significantly speed up the adoption of fantasy-land specification.


The idea inspired by transducers protocol, seems like it worked out for them pretty well.

See also discussion on Gitter: https://gitter.im/fantasyland/fantasy-land?at=553cb82d20328f114ca36f0f

Filterable algebra?

.map and .chain are cool for writing higher order functions over things.

Another primitive I use a lot is .filter and I don't know how to implement in terms of .map / .ap / .chain.

Is there an algebra for it?

How to use libraries

Suggestion: Give a short tutorial on README.MD on how to install and use libraries. Or create a single standalone file.

This is a dumb question I'm sure - so thanks in advance. But how am I supposed to go about and use these libraries? I see they use requirejs so I downloaded that library and learned how to use it.

I then downloaded the fantasyland libraries I needed using bower.js. I set up the require config file using bower-requirejs library.

I expected that I would do something like this:

define(['lodash', 'bilby', 'fantasy-lenses'], function(_, b, fantasy){
  //My code
}

Which give the error:

Uncaught Error: Module name "daggy" has not been loaded yet for context: _.

So I go through and add all the libraries and it gives me the error:

Uncaught TypeError: Cannot read property 'Lens' of undefined

Traversable

Traversable is pretty neat. What do we say about adding this to the spec? Of course it depends on #7 being approved. Is there standard nomenclature for either traverse or sequence? Which one are we suggesting in the spec? Or do we allow either, with a derivable implementation for the other?

Define Pointed in terms of `of`

Consider defining Pointed in terms of of, and let Monad inherit from Pointed.

Motivation:

  1. All the Semigroup and Monoid instances here could be instances of Pointed, which would readily indicate how to lift values into the instances.
  2. The hierarchy outlined in this post.

Project maintenance

Whether to support this project (fantasy-*) in the future and maintenance npm packages?

Decouple Monad from Applicative

I'm afraid it's not always correct to assume that a Monad is also an Applicative. At least I tried to implement the specs into Bacon.js today, for an excersise, and run into issues because of this assumption. I'm not sure how familiar you're with Bacon.js, but I'll try to explain the case anyway.

Now an EventStream in Bacon.js is clearly a Monadic structure: the flatMap method (aliased now as chain) of EventStream has one parameter which is a function that creates a new EventStream for each value in the original stream. In combination with EventStream.of we have a nice Monad. Except.

The Applicative interface for EventStreams doesn't make much sense, at least if based on flatMap: the result stream a.ap(b) would take apply each function from the source stream to all (or one?) subsequent elements in the stream b. It would make more sense to base ap on combine or even zip, but I'd rather not have EventStream implement Applicative because of this ambiguity.

In Haskell, you can declare Monad without Applicative. Why not in Fantasy Land?

The fantasy-land version of Bacon.js is in the fantasy-land branch. I'm planning to bring that to master, if I can come up with a nice solution. The current EventStream/Applicative one seems to be compliant, but I would never use it because Applicative through flatMap just makes no sense.

I'd like to have EventStream implement Functor and Monad (no Applicative), and Property implement Functor and Applicative (and a Duck Monad (Property.flatMap returns an instance of EventStream)).

Please ask for more details if this made no sense to you :)

Ordering of parallel `chain`s

Sourcing from a when.js issue:

p.chain(f).chain(g);
p.chain(h);

In the presence of side-effects, the order of execution matters. If the order is FHG (i.e. breadth-first), and h has a side-effect, then g may be affected by a totally separate chain (and indeed, p.chain(h) could be in an entirely different part of the file).

We could stick with precedent and push the concern downstream, but I want to at least raise the issue as something that should be considered somewhere along the line.

why these identifiers?

What is the reasoning behind the choice of identifiers u, v, w, x, and y in the specification? I can see why a, b, f, and m were chosen in the contexts they're used, but I can't do the same for the letters near the end of the alphabet.

Add a license & contributing guidelines

It should be clear what license the documentation and test suite are under, and perhaps a CONTRIBUTING file that makes clear that pull requests are implicit license. This latter is a bit litigious but I've seen it around sometimes.

Minimal implementation

Without any particular background in Haskell or any other pure functional algebraic approach, but with an inkling that this approach might be super useful in a wide variety of situations, I've attempted to create a minimal implementation of the structures described in this spec:

https://github.com/jden/fancy

Consider it a null implementation, if you will. I'd love to see examples of generic functions which can operate without error (even if semantically nonsensically) on this minimal structure.

I tried to implement the spec as closely as possible in the tests.

monad.constructor.of vs monad.of

Why complicate things with constructor. Let's just have every monad have two properties.

Back compat with promises for constructor.of may be a bad idea if we're going to rename then anyway.

We can also use monad.point if we prefer.

Cofoldable

As mentioned here I'd like to propose a Cofoldable. There's detailed information about it here

The idea is that while Foldable and Cofoldable are lawless alone, together you can suggest some laws on them.

It should have one of two methods:

  • fromArray :: [a] -> f a
  • unfold

I'm actually unsure on the definition of unfold Should it be (a -> b -> b) -> b -> b -> f a as in the definition for `build in the link, or something else? In any case, one can be derived from the other.

Please discuss.

Add Then (>>) to monad spec

For example:

Id.prototype.then = function (m) {
    return m;
}
Promise.prototype.then = function (m) {
    var promise = this;
    return new Promise (function (resolve) {
        return promise.fork (function (dontCare) {
            return m.fork (resolve);
        });
    });
}

Then you could have code like this:

somethingToDo (x) // Returns Future
    .chain (thisAlsoReturnsAFuture)
    .then  (justDoFinalFuture)

instead of:

somethingToDo (x) // Returns Future
    .chain (thisAlsoReturnsAFuture)
    .chain (konst (justDoFinalFuture))

Thoughts?

Exception handling examples

I was reading through http://book.realworldhaskell.org/read/error-handling.html and trying to see how it would be adapted to Fantasy Land js, but struggling a little bit. I would really appreciate if anyone could come up with some example code to deal with this situation:

Assume some Fantasy Land compliant promises implementation:

var err = Promise.reject(new Error('broken'))
var ok = Promise.of(10)

var sum = liftA2(err, ok, function (a, b) {
  // this should never be called
  return a + b
})
return sum

// later, in some other scope, where I only have access to sum:

sum.chain(function (sum) {
  // this should also never be called
})

// how do I get the error message?

Fantasy Land compliant library

https://github.com/leoasis/fnky

I implemented a library for functional programming Javascript, with the common constructs like functor, applicative, monad and monoid, following the Fantasy Land spec.

It also includes some common implementations, like Maybe and Either.

I'd appreciate any suggestions from you guys, and things you may see that break the spec in any way. I'd like your approval to claim that it follows the spec (and put the badge there).

Obviously it's not complete, but I plan to keep building on it.

Semigroup definition

is

a.concat(b).concat(c) is equivalent to a.concat(b.concat(c))

the same as

a.concat(b).concat(c) is equivalent to b.concat(c).concat(a)

I would find the second definition more intuitively readable about what the law means

Feedback from the outside

I feel like I am entering the depths of a seldom visited rocky recess. Hello.

I have been diving into functional paradigms, increasingly, for at least a year. I am interested in and actively trying to author my javascript-based work with a functional hand.

Given this, I felt quite lucky to fall upon this [Fantasy Land] project given it appears to be helping translate ideas from purer languages into javascript.

Language-wise I have focused my functional learning efforts to date on Haskell, because it/its community appears to tackle the matter rigorously and have pioneered certain or many functional programming breakthroughs.

I was surprised to find however that fantasy-land terminology differs from haskell's insofar as option instead of maybe, and moands wherein I know they require a return (sometimes called unit) and bind method but I've only seen of and chain mentioned in Fantasy Land (Still not sure but I'm assuming of === return and chain === bind?).

Is this spec going against conventional functional naming or is it Haskell that deviates?

Describe semigroups

Wikipedia describes semigroups as a set that has a binary relation. You should probably come up with something a little bit more concrete and grounded though.

define equality

Spec tends to refer to equality, which is not defined:

u.map(function(a) { return a; })) equal `u`

What kind of equality are we talking about == or === or likely something else. If not later than array is no longer a functor.

Motivation

Every algebraic data type should contain motivation for WHY it's a useful abstraction.

It took me a while to understand why any of these are useful abstractions.

Why no "join" operation?

This is really for my own curiosity and learning, but I'm wondering why the spec doesn't explicitly call for a "join" operation for monads?

On one hand, I can see how it's implicit in chain. On the other, it seems like many (most? all?) times, chain can be defined in terms of map and join. Perhaps it's because chain is the more often used operation, thus making it a "better" public API to specify, and join is typically a means to an end? (the end being to implement chain)

Thanks for helping me understand!

Foldable

Use reduceRight as the method name. Makes Array compatible.

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.