Open joneshf opened 7 years ago
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 .
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
.
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.
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.
Is #290 a duplicate of this?
@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.
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
@gabejohnson Perhaps we need a meta-spec to specify how to talk about specs like this one. ;)
Sorry, I haven't been paying much attention to the hierarchy.