(Co/Contra)Functor and Comonad

Why are Cofunctor and Comonad classes not a part of the base library? I recently defined a data type (Control.Cofunctor.Ticker in monad-coroutine on Hackage) that happens to be a co-functor, or contra-functor if you prefer. In other words, it can implement the following function:
cofmap :: (a -> b) -> cf b -> cf a
I wanted to define a proper instance for it, but to my surprise I discovered that I couldn't. Not only is the class not defined in base, the only package I could find on Hackage that defines it is category-extras. This is a huge package I'd rather not have as a dependency, so I opted not to declare any instance. Later on I found that this question has been raised before by *Conal Elliott*, nearly four years ago. http://www.haskell.org/pipermail/libraries/2007-January/006740.html The result was the TypeCompose package, which presents a decent solution. I still can't think of any harm in having a proper class declaration in the base library: if you don't need it, you don't need to know it. But without the class declaration in the base library (or in some other obvious package) every other released library must either lack the instance declarations or declare the class itself and risk clashes. This is not some obscure class you've never encountered, by the way: any "consumer" of data is a cofunctor. All regexp data types, for example, are cofunctor instances - or would be if there was a class to declare them instances of. The same question extends to Comonad. I am not too familiar with this area so there may be fewer potential instances of the class, but I remember there was quite a bit of buzz around comonads a few years ago. Judging by a cursory Hayoo search, if anything the situation is worse than with Cofunctor: there are multiple incompatible declarations of the class scattered in various libraries that need it: ad, category-extras, data-category, rope. There is also evidence of undeclared Comonad instances: see the ListZipper and value-supply libraries. So, is it time to add these two classes to the base library?

On 12/23/10 16:43, Mario Blažević wrote:
Cofunctor and Comonad
IMHO, as you say, there is only one design of cofunctor. class Cofunctor cf where cofmap :: (a -> b) -> cf b -> cf a The only question is capitalization and spelling.* Since there are multiple designs of Comonad floating around, it'll take slightly more design work to make sure a standard design works for everyone. -Isaac *(CoFunctor or Cofunctor, cofmap or comap etc. IMHO your choices are fine. And to choose a module to put it in.).

On Wed, Dec 29, 2010 at 7:37 AM, Ian Lynagh
On Thu, Dec 23, 2010 at 04:43:24PM -0500, Mario Blažević wrote:
Why are Cofunctor and Comonad classes not a part of the base library?
Base is already too large IMO. Why do these classes /need/ to be in base, rather than another package?
Classes in general /need/ to be declared in an easy to find and unambiguously recommended place. Otherwise people either won't declare their instances, or will declare incompatible classes themselves. Class dependencies also won't be declared, because nobody would go to the trouble of declaring a more generic type that depends on a class nobody's heard of. The best place according to the "unambiguously recommended and easy to find" criteria is the base library. The next best would be a Hackage library with minimal dependencies, whose name exactly corresponds to the class - contrafunctor or control-contrafunctor, for example. This solution would be good enough for anybody (including myself) who already knows they need to declare or use a class instance, but most people would remain unaware of them.

On 29 December 2010 16:17, Mario Blažević
The best place according to the "unambiguously recommended and easy to find" criteria is the base library. The next best would be a Hackage library with minimal dependencies, whose name exactly corresponds to the class - contrafunctor or control-contrafunctor, for example.
Personally, I'm at best lukewarm about minimal Hackage-hosted packages for Base-like things. As Cabal dependencies are on version numbers rather than capability (c.f. autoconf) I see them as much a cost as a benefit, so I don't want to depend on things that aren't doing some functional work. Would a "Base 2" or "BaseExts" library that amalgamates the "less central" structures like Comonad, Bifunctor, Semigroup, ... have value to the community?

Is the problem the size of base per-se, or is it more the number of things in base for which the design might ideally be subject to change? If it's the latter, then that should maybe be the main consideration. (Personally I think I'd like to see 'Comonad' in base...) --Ben On 29 Dec 2010, at 12:37, Ian Lynagh wrote:
On Thu, Dec 23, 2010 at 04:43:24PM -0500, Mario Blažević wrote:
Why are Cofunctor and Comonad classes not a part of the base library?
Base is already too large IMO. Why do these classes /need/ to be in base, rather than another package?
Thanks Ian
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

On Fri, Dec 31, 2010 at 09:00:57AM +0000, Ben Moseley wrote:
Is the problem the size of base per-se, or is it more the number of things in base for which the design might ideally be subject to change?
It's a combination of many small things. base gets a little bigger, and is a little slower to compile. It's another thing waiting to get tangled up in base's dependency loops. It's another thing the libraries@ reviewers and base committers are responsible for. This change alone isn't a major issue; it's a death-by-a-thousand-cuts problem. Thanks Ian
participants (5)
-
Ben Moseley
-
Ian Lynagh
-
Isaac Dupree
-
Mario Blažević
-
Stephen Tetley