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

Why do Bifunctor and Profunctor need to implement Functor? #214

Open
joneshf opened this issue Dec 17, 2016 · 8 comments
Open

Why do Bifunctor and Profunctor need to implement Functor? #214

joneshf opened this issue Dec 17, 2016 · 8 comments

Comments

@joneshf
Copy link
Member

joneshf commented Dec 17, 2016

Sorry, I haven't been paying much attention to the hierarchy.

@rpominov
Copy link
Member

I can only guess, but maybe because we wanted to make a.bimap(id, f) == a.map(f) and a.promap(id, f) == a.map(f). Maybe we should add corresponding laws?

Btw, If we do so, we'll basically move another two derivations to laws #188 .

@joneshf
Copy link
Member Author

joneshf commented Dec 18, 2016

Ah, I see. That's pretty confusing since something like Either can implement Bifunctor and can't implement Functor, but Either a can't implement Bifunctor and can implement Functor.

@rpominov
Copy link
Member

Yeah, confusing it is. Another mismatch in Haskell vs JavaScript environments. In JS we usually think about just an Either type, without considering number of type arguments. And we just think that Either implements Functor and Bifunctor. At least this is how I usually tend to think about it.

Not sure what we should do with the spec, tbh. Probably remove the dependency, but I personally kinda like if spec demands that a.bimap(id, f) == a.map(f) for example. Although again not sure what that means in terms of Haskell-like type system.

@rjmk
Copy link
Contributor

rjmk commented Dec 19, 2016

I would like us to have the ability to talk about these kinds of relationships.

I am uncomfortable with talking about a type implementing both bifunctor and functor. I am slightly uncomfortable with the way the spec allows talking about functor instances for Either (rather than Either a).

So I vote to remove the dependency and for us to work out a way to talk about (a) the kinds of types (b) the partial application of types.

@masaeedu
Copy link

Is #290 a duplicate of this?

@gabejohnson
Copy link
Member

@masaeedu I don't think so. This issue is concerned with how the spec talks

about (a) the kinds of types (b) the partial application of types.

or fails to do so.

There appear to be two ways in which constraints are specified in the spec which are illustrated in the Bifunctor definition.

A value that implements the Bifunctor specification must also implement the Functor specification.

and

bimap :: Bifunctor f => f a c ~> (a -> b, c -> d) -> f b d

In the former case, a value (not type) that implements the Bifunctor algebra is constrained to values which also implement the Functor algebra.

In the latter case, a type (not a value) is defined as implementing the Bifunctor algebra if it has a bimap method with the signature f a c ~> (a -> b, c -> d) -> f b d and satisfies the laws stated in the previous section.

I think this confusion could be eliminated if we used a class declaration-like notation

(Functor (f a), Functor (f b)) => Bifunctor f where
  bimap :: f a c ~> (a -> b, c -> d) -> f b d

The "Type signature notation" section introduced in #223 mentions "typeclass" while discussing constraints on type variables without giving a definition. The implication is that "typeclass" is synonymous with the term "algebra" used elsewhere in the spec.

@gabejohnson
Copy link
Member

Even better (and addressing #290) would be

(Functor (f a), Functor (f b)) => Bifunctor f where
  bimap :: f a c ~> (a -> b, c -> d) -> f b d
  lmap  :: f a c ~> (a -> b) -> f b c

@masaeedu
Copy link

@gabejohnson Perhaps we need a meta-spec to specify how to talk about specs like this one. ;)

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

5 participants