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

Consider integrating type class morphisms #6

Open
briancavalier opened this issue Feb 13, 2016 · 3 comments
Open

Consider integrating type class morphisms #6

briancavalier opened this issue Feb 13, 2016 · 3 comments

Comments

@briancavalier
Copy link
Owner

See Conal Elliott's paper on denotational design and type class morphisms, or any of his recent talks based on it. One of the main points in the paper is that defining type class instances "can sometimes be derived mechanically from desired type class morphisms". Applying that to define, say, Promise's functor instance might go something like (using haskell-like syntax here, where fmap is the functor operation):

fmap f (Promise a) = Promise (fmap f a)

IOW, an fmapped future value is the future fmapped value. Or as it's stated in the paper: "The instance’s meaning follows the meaning’s instance"

Functor Example

That opens up some interesting possibilities .. for example:

fmap f (Promise [a]) = Promise (fmap f [a])

If we have a promise for an array of numbers and want add 1 to each number in the array, in creed 1.0, we have to map twice:

import { fulfill } from 'creed';
const ints = fulfill([1,2,3]);
const intsPlusOne = ints.map(a => a.map(x => x+1));

However, using the fmap definition above:

import { fulfill } from 'creed';
const ints = fulfill([1,2,3]);
const intsPlusOne = ints.map(x => x+1);

The exact same thing would work with a promise for a single number:

import { fulfill } from 'creed';
const one = fulfill(1);
const two = one.map(x => x+1);

Or for a promise for a tree of numbers, or a promise for a promise of a number, and so on. Applicative would likely be similar to Functor.

Questions

What about type classes for which there are two (or more) interesting behaviors? For example, creed's Promise has a monoid instance, with never as the identity element and concat returning the earlier of the two promises to settle. IOW, it doesn't rely on the monoid instance of the value type, but rather only on the time of the two promises.

That monoid definition is useful because it represents racing.

A monoid instance defined using the ideas in the paper would use the identity element of the value type (How would this even work??), and concat would apply the concat operation of the value type. IOW, concatenating two future arrays would produce a future concatenated array.

concat (Promise [a]) (Promise [a]) = Promise (concat [a] [a])

That's probably also useful, and I have no idea how to deal with wanting two monoid instances for Promise.

I also have no idea yet how to define a monad instance for Promise using this approach, if it's useful, or even possible. As far as I can tell, the paper doesn't much (if any) guidance on applying the technique for monad instances.

@davidchase
Copy link
Contributor

adding from our chat on gitter:

I thought of a way to deal with the “two monoid instances” problem here:
i.e. the tension between wanting concat to be race vs concat’ing the promise values
there is a related typeclass called Alternative. If something has both a Monoid and Applicative (which creed promises do), it can also have an Alternative
so Alternative could be race, and Monoid could be a typeclass morphism that concats the two values
unfortunately, fantasyland doesn’t yet provide a definition of Alternative
tho there is some discussion: fantasyland/fantasy-land#117

i found purescript/purescript-control#6 (comment)
to be particular interesting insight from hardy

so creed is applicative because of ap and fulfill and a monoid because of never and concat is that correct?

and alternative seems to be similar to the monoid
at least for an array [] empty and (++)(concat)

so however back to my intial question it seems like the OP of fantasyland/fantasy-land#117 wants or instead of concat ?

@safareli
Copy link

Related issues in FL on Alternative:

@briancavalier
Copy link
Owner Author

Thanks @safareli. We just added Alt, Plus, and Alternative: https://github.com/briancavalier/creed#fantasy-land. We're planning to switch to a value-based monoid in 2.x, probably functor as well.

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