Skip to content
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

Free can openers #168

Closed
onmyway133 opened this issue Sep 14, 2015 · 3 comments
Closed

Free can openers #168

onmyway133 opened this issue Sep 14, 2015 · 3 comments

Comments

@onmyway133
Copy link

Hi, I'm reading Free can openers

map is defined using ap

I mentioned earlier that of/ap is equivalent to map. We can use this knowledge to define map for free:

// map derived from of/ap
X.prototype.map = function(f) {
  return this.constructor.of(f).ap(this);
}

But ap is defined using map, so is there a cycle here?

We can define ap like so:

Container.prototype.ap = function(other_container) {
  return other_container.map(this.__value);
}

map is defined using chain

Monads are at the top of the food chain, so to speak, so if we have chain, we get functor and applicative for free:

// map derived from chain
X.prototype.map = function(f) {
  var m = this;
  return m.chain(function(a) {
    return m.constructor.of(f(a));
  });
}

But in Chapter 9, chain is defined using map and join, so is there a cycle here?

//  chain :: Monad m => (a -> m b) -> m a -> m b
var chain = curry(function(f, m){
  return m.map(f).join(); // or compose(join, map(f))(m)
});
@zerkms
Copy link

zerkms commented Sep 14, 2015

But ap is defined using map, so is there a cycle here?

It's actually frequent to provide generic "cycled" (or mutual, not sure what would be a proper term here) implementations for base types and demand a user to provide a particular implementations for specific types.

Example:

class  Eq a  where
    (==), (/=) :: a -> a -> Bool

        -- Minimal complete definition:
        --      (==) or (/=)
    x /= y     =  not (x == y)
    x == y     =  not (x /= y)

So as you can see == and /= are implemented in terms of the other. And a particular instance must provide either (or both).

In case of the book I'm sure it was just an example that it might be implemented like that.

@DrBoolean
Copy link

Yep! It is necessary to define one or the other manually, but then you get it for free.

@onmyway133
Copy link
Author

@zerkms @DrBoolean thanks, I think we should state "minimal complete definition" in the book

@KtorZ KtorZ closed this as completed in ab1353b Feb 20, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants