Re: In opposition of Functor as super-class of Monad

2013-07-08 Thread Wvv
http://haskell.1045720.n5.nabble.com/Interfaces-the-Golden-Path-of-Haskell-tt5732208.html
 

With this Haskell extension it could be possibe to implement both (Monad m)
and (Applicative m = Monad m). Not only both, we could define a lot of
Monad for many users.



--
View this message in context: 
http://haskell.1045720.n5.nabble.com/Re-In-opposition-of-Functor-as-super-class-of-Monad-tp5719389p5732573.html
Sent from the Haskell - Haskell-prime mailing list archive at Nabble.com.

___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Re: In opposition of Functor as super-class of Monad

2012-10-25 Thread Ben Millwood
The major advantage that I see of making Applicative a superclass of
Monad is actually not anywhere to do with the data types or instances,
but rather to do with functions that operate on the class. For
example, the liftM* family of functions becomes entirely redundant,
and can be eliminated in favour of liftA*, which reduces the number of
arbitrary choices we need to make and understand. As another example,
we sometimes want to use functions (like void or fmap) that work with
Functor and functions (like join) that need Monad in the same
(polymorphic) code. We then have to state *both* constraints in the
context for the code, despite the fact that if one is satisfied, the
other must surely be. For example, defining instance Functor (StateT s
m) you have to choose whether to use the context (Monad m) or (Functor
m): the latter is more general, but requires your programs that use
fmap *and* bind to specify (Monad m, Functor m), and the former is
almost always what's used in practice anyway. This tension just
doesn't exist if one is a superclass of the other.

Some code will break, yes, but I think most people would agree that
the presence of a Monad instance with no corresponding Applicative
instance is a bug anyway, and should be fixed.

(Note that if Applicative and Monad are both defined for the same
type, it is required by the Applicative docs that return = pure and
* = ap, at least extensionally. Of course the implementation can be
cleverer, but if you want it to be actually /different/ in behaviour,
please use a newtype).

___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Re: In opposition of Functor as super-class of Monad

2012-10-25 Thread Tony Morris
I should have been clearer sorry. I should hope not that Functor -
Applicative - Monad.

Perhaps I do not understand the purpose of this thread, but fixing the
hierarchy in this way is a mistake of similar magnitude to the original
position -- one that I would cringe at seeing repeated. That is why I
thought such a discussion was on-topic.


On 25/10/12 10:12, Ben Franksen wrote:
 Tony Morris wrote:
 I should hope not. The identity element (return, coreturn, mempty, pure,
 Category.id) is almost never needed.

 * http://hackage.haskell.org/package/semigroupoids
 * https://gist.github.com/3871764
 Off-topic. Feel free to start a new thread named The bombastic one-and-true 
 class hierarchy I always wanted to have. These proposals have their merits, 
 and I greatly respect the category theoretic knowledge that went into them 
 -- but this is another discussion. This thread refers to a rather modest 
 correction in the standard libraries, not a complete re-design. The idea is 
 to fix something that is widely accepted as an unfortunate ommision (in 
 fact, Oleg's comment is one of the very few that question the idea of adding 
 super class constraints to Monad in principle).

 BTW, it is unclear what your I hope not refers to, since in both of the 
 hierarchies you linked to Applicative *is* a super class of Monad.

 Cheers

 On 25/10/12 04:49, Ben Franksen wrote:
 First, let me make it clear that nowadays we are of course (I hope!) 
 talking 
 about making not only Functor, but Applicative a super-class of Monad (so 
 Functor becomes a super-class by transitivity).

 Petr P wrote:
 The main objections were that it would break existing code and that it
 would lead to code duplication. The former is serious, [...]

 To address the first objection:
 I don't buy this it breaks lots of code argument. Adding the missing 
 instances is a complete no-brainer; as you wrote:

 instance Applicative ... where
 pure   = return
 (*)  = ap
 instance Functor ... where
 fmap   = liftM
 I do not think it is unreasonable to expect people to add such a simple 
 and 
 practically automatic fix to some old programs in the interest of 
 cleaning 
 up an old wart (and almost everyone agrees that this would be a good 
 thing, 
 in principle).

 BTW, I guess most programs already contain the Functor instances (but 
 maybe 
 not Applicative, as it is newer).

 I agree with Petr Pudlak that code duplication is not an issue, see 
 above. 
 And yes, these automatic instances may have stronger super-class 
 constraints than strictly necessary. So what? The program didn't need the 
 Functor (or Applicative) instance anyway (or it already would have 
 defined 
 it, in which case no change would be needed at all).

 Default superclass instances strike me as a complicated proposal for 
 solving trivial problems. The switch in Control.Exception (from data 
 Exception to class Exception) was much more disrupting, adapting programs 
 meant lots of changes everywhere exceptions are handled, not just adding 
 some trivial instances. Still people managed the transition.

 Cheers



-- 
Tony Morris
http://tmorris.net/



___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Re: In opposition of Functor as super-class of Monad

2012-10-25 Thread Edward Kmett
Tony, I think you misparsed the proposal. 

The ...'s were for specific monads indicating the additional work required for 
each Monad.

I think the only real proposal on the table is the obvious one of adding 
Applicative as a superclass of monad.

From there there are a couple of incremental improvements that could be made 
like adding the unimplemented superclass defaults or adding the equivalent of 
DefaultSignatures to the language spec to reduce the burden on Monad 
implementors.

In practice I think either of those extensions would be premature to add to the 
language specification at this time.

I would be 100% behind adding the Applicative constraint as a superclass of 
Monad and even perhaps of some bikeshedding, like exporting Applicative from 
the Prelude, because otherwise you can't define a Monad without an import, 
while you can now.

I would be strongly against requiring superclass defaults or DefaultSignatures 
in the haskell standard, however. The former is a largely untested point in the 
design space and the latter has issues where it tightly couples classes with 
their dependencies, leading to unbreakable cycles between classes that all have 
to be defined together and poor engineering practices.

Best,
--Edward


On Oct 25, 2012, at 5:46 PM, Tony Morris tonymor...@gmail.com wrote:

 I should have been clearer sorry. I should hope not that Functor -
 Applicative - Monad.
 
 Perhaps I do not understand the purpose of this thread, but fixing the
 hierarchy in this way is a mistake of similar magnitude to the original
 position -- one that I would cringe at seeing repeated. That is why I
 thought such a discussion was on-topic.
 
 
 On 25/10/12 10:12, Ben Franksen wrote:
 Tony Morris wrote:
 I should hope not. The identity element (return, coreturn, mempty, pure,
 Category.id) is almost never needed.
 
 * http://hackage.haskell.org/package/semigroupoids
 * https://gist.github.com/3871764
 Off-topic. Feel free to start a new thread named The bombastic one-and-true 
 class hierarchy I always wanted to have. These proposals have their merits, 
 and I greatly respect the category theoretic knowledge that went into them 
 -- but this is another discussion. This thread refers to a rather modest 
 correction in the standard libraries, not a complete re-design. The idea is 
 to fix something that is widely accepted as an unfortunate ommision (in 
 fact, Oleg's comment is one of the very few that question the idea of adding 
 super class constraints to Monad in principle).
 
 BTW, it is unclear what your I hope not refers to, since in both of the 
 hierarchies you linked to Applicative *is* a super class of Monad.
 
 Cheers
 
 On 25/10/12 04:49, Ben Franksen wrote:
 First, let me make it clear that nowadays we are of course (I hope!)
 talking 
 about making not only Functor, but Applicative a super-class of Monad (so 
 Functor becomes a super-class by transitivity).
 
 Petr P wrote:
 The main objections were that it would break existing code and that it
 would lead to code duplication. The former is serious, [...]
 
 To address the first objection:
 I don't buy this it breaks lots of code argument. Adding the missing 
 instances is a complete no-brainer; as you wrote:
 
 instance Applicative ... where
pure   = return
(*)  = ap
 instance Functor ... where
fmap   = liftM
 I do not think it is unreasonable to expect people to add such a simple
 and 
 practically automatic fix to some old programs in the interest of
 cleaning 
 up an old wart (and almost everyone agrees that this would be a good
 thing, 
 in principle).
 
 BTW, I guess most programs already contain the Functor instances (but
 maybe 
 not Applicative, as it is newer).
 
 I agree with Petr Pudlak that code duplication is not an issue, see
 above. 
 And yes, these automatic instances may have stronger super-class 
 constraints than strictly necessary. So what? The program didn't need the 
 Functor (or Applicative) instance anyway (or it already would have
 defined 
 it, in which case no change would be needed at all).
 
 Default superclass instances strike me as a complicated proposal for 
 solving trivial problems. The switch in Control.Exception (from data 
 Exception to class Exception) was much more disrupting, adapting programs 
 meant lots of changes everywhere exceptions are handled, not just adding 
 some trivial instances. Still people managed the transition.
 
 Cheers
 
 
 -- 
 Tony Morris
 http://tmorris.net/
 
 
 
 ___
 Haskell-prime mailing list
 Haskell-prime@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-prime

___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Re: In opposition of Functor as super-class of Monad

2012-10-25 Thread Tony Morris
OK, sorry about the noise!

On 26/10/12 09:41, Edward Kmett wrote:
 Tony, I think you misparsed the proposal. 

 The ...'s were for specific monads indicating the additional work required 
 for each Monad.

 I think the only real proposal on the table is the obvious one of adding 
 Applicative as a superclass of monad.

 From there there are a couple of incremental improvements that could be 
 made like adding the unimplemented superclass defaults or adding the 
 equivalent of DefaultSignatures to the language spec to reduce the burden on 
 Monad implementors.

 In practice I think either of those extensions would be premature to add to 
 the language specification at this time.

 I would be 100% behind adding the Applicative constraint as a superclass of 
 Monad and even perhaps of some bikeshedding, like exporting Applicative from 
 the Prelude, because otherwise you can't define a Monad without an import, 
 while you can now.

 I would be strongly against requiring superclass defaults or 
 DefaultSignatures in the haskell standard, however. The former is a largely 
 untested point in the design space and the latter has issues where it tightly 
 couples classes with their dependencies, leading to unbreakable cycles 
 between classes that all have to be defined together and poor engineering 
 practices.

 Best,
 --Edward


 On Oct 25, 2012, at 5:46 PM, Tony Morris tonymor...@gmail.com wrote:

 I should have been clearer sorry. I should hope not that Functor -
 Applicative - Monad.

 Perhaps I do not understand the purpose of this thread, but fixing the
 hierarchy in this way is a mistake of similar magnitude to the original
 position -- one that I would cringe at seeing repeated. That is why I
 thought such a discussion was on-topic.


 On 25/10/12 10:12, Ben Franksen wrote:
 Tony Morris wrote:
 I should hope not. The identity element (return, coreturn, mempty, pure,
 Category.id) is almost never needed.

 * http://hackage.haskell.org/package/semigroupoids
 * https://gist.github.com/3871764
 Off-topic. Feel free to start a new thread named The bombastic 
 one-and-true 
 class hierarchy I always wanted to have. These proposals have their 
 merits, 
 and I greatly respect the category theoretic knowledge that went into them 
 -- but this is another discussion. This thread refers to a rather modest 
 correction in the standard libraries, not a complete re-design. The idea is 
 to fix something that is widely accepted as an unfortunate ommision (in 
 fact, Oleg's comment is one of the very few that question the idea of 
 adding 
 super class constraints to Monad in principle).

 BTW, it is unclear what your I hope not refers to, since in both of the 
 hierarchies you linked to Applicative *is* a super class of Monad.

 Cheers

 On 25/10/12 04:49, Ben Franksen wrote:
 First, let me make it clear that nowadays we are of course (I hope!)
 talking 
 about making not only Functor, but Applicative a super-class of Monad (so 
 Functor becomes a super-class by transitivity).

 Petr P wrote:
 The main objections were that it would break existing code and that it
 would lead to code duplication. The former is serious, [...]

 To address the first objection:
 I don't buy this it breaks lots of code argument. Adding the missing 
 instances is a complete no-brainer; as you wrote:

 instance Applicative ... where
pure   = return
(*)  = ap
 instance Functor ... where
fmap   = liftM
 I do not think it is unreasonable to expect people to add such a simple
 and 
 practically automatic fix to some old programs in the interest of
 cleaning 
 up an old wart (and almost everyone agrees that this would be a good
 thing, 
 in principle).

 BTW, I guess most programs already contain the Functor instances (but
 maybe 
 not Applicative, as it is newer).

 I agree with Petr Pudlak that code duplication is not an issue, see
 above. 
 And yes, these automatic instances may have stronger super-class 
 constraints than strictly necessary. So what? The program didn't need the 
 Functor (or Applicative) instance anyway (or it already would have
 defined 
 it, in which case no change would be needed at all).

 Default superclass instances strike me as a complicated proposal for 
 solving trivial problems. The switch in Control.Exception (from data 
 Exception to class Exception) was much more disrupting, adapting programs 
 meant lots of changes everywhere exceptions are handled, not just adding 
 some trivial instances. Still people managed the transition.

 Cheers

 -- 
 Tony Morris
 http://tmorris.net/



 ___
 Haskell-prime mailing list
 Haskell-prime@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-prime


-- 
Tony Morris
http://tmorris.net/



___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Re: In opposition of Functor as super-class of Monad

2012-10-24 Thread S. Doaitse Swierstra
There are very good reasons for not following this road; indeed everything 
which is a Monad can also be made an instance of Applicative. But more often 
than not we want to have a more specific implementation. Because Applicative is 
less general, there is in general more that you can do with it.

An analogue is the relation between regular grammars and context-free grammars; 
indeed, once we have the latter concept we might argue that we do not need the 
first one any more. But if we know that something is in the first category we 
can do all kins of nice things which we cannot do with conxet-free grammars, 
such as constructing a finite state machine for recognising sentences.

You proposal would introduce overlapping instances is such cases where we want 
to give a ``better'' implementation in case we know we are dealing with the 
more restricted case.

I have explained this phenomenon for the first time in:


@inproceedings{SwieDupo96,
Author = {Swierstra, S. D. and Duponcheel, L.},
Booktitle = {Advanced Functional Programming},
Date-Added = {2009-01-04 17:21:54 +0100},
Date-Modified = {2009-01-04 17:21:54 +0100},
Editor = {Launchbury, John and Meijer, Erik and Sheard, Tim},
Pages = {184-207},
Publisher = {Springer-Verlag},
Series = {LNCS-Tutorial},
Title = {Deterministic, Error-Correcting Combinator Parsers},
Urlpdf = 
{http://www.cs.uu.nl/people/doaitse/Papers/1996/DetErrCorrComPars.pdf},
Volume = {1129},
Year = {1996}}

If you look at the uu-parsinglib library you will see that the Applicative 
instance of the parsers used there is definitely more involved that what you 
can do with the monadic interface. Your proposal would ruin this library.

Unless we have things like e.g. named instances, the possibility to choose 
between overlapping instances, etc. I think we should leave things the way they 
are; the only reason I see for having superclasses is to be able to use 
functions from those classes in the default implementations of functions in the 
new class, and to group functionality coming from several classes.

 Doaitse












On Oct 24, 2012, at 10:01 , Petr P petr@gmail.com
 wrote:

  Hi,
 
 I was thinking lately about the well known problem that Monad is
 neither Functor nor Applicative. As I understand, it is caused by some
 historical issues. What I like about Haskell is that it allows to
 describe very nicely what different objects actually are - something
 that I find very important for programming. And this issue violates
 this principle.
 
 This has been discussed here more than year ago in
 http://www.haskell.org/pipermail/haskell-prime/2011-January/003312.html
 :
 
 On 1/4/11 11:24, oleg at okmij.org wrote:
 I'd like to argue in opposition of making Functor a super-class of
 Monad. I would argue that superclass constraints are not the right
 tool for expressing mathematical relationship such that all monads are
 functors and applicatives.
 
 Then argument is practical. It seems that making Functor a superclass
 of Monad makes defining new monad instances more of a chore, leading
 to code duplication. To me, code duplication is a sign that an
 abstraction is missing or misused.
 ...
 
 The main objections were that it would break existing code and that it
 would lead to code duplication. The former is serious, the second can
 be easily solved by standard Haskell, since one can define
 
 instance Applicative ... where
pure   = return
(*)  = ap
 instance Functor ... where
fmap   = liftM
 
 To address the first objection:
 AFAIK nobody mentioned the Default superclass instances proposal:
 http://hackage.haskell.org/trac/ghc/wiki/DefaultSuperclassInstances
 To give an example how it would work:
 
class Applicative f = Monad f where
  (=) :: f a - (a - f b) - f b
  ...
  instance Applicative f where
ff * fs = ff = \ f - fs = \ s - return (f s)
...
 
 This says that if somebody defines an instance of Monad it
 automatically becomes an instance of Applicative as defined in the
 nested instance block. So there is no need to define
 Applicative/Functor explicitly, making existing code work.
 
 Implementing this proposal would allow making Monad to extend Functor
 and Applicative without breaking existing code. Moreover, this would
 simplify other things, for example it would be possible to define an
 instance of Traversable and the instances for Functor and Foldable
 would be defined implicitly using fmapDefault and foldMapDefault. I'm
 sure there are many other cases where splitting type classes into a
 more fine-grained hierarchy would be beneficial, and the main reason
 against it is simply not to break compatibility with existing code.
 
 IMHO this would be worthwhile to consider for some future revision of Haskell.
 
  Best regards,
  Petr Pudlak
 
 ___
 Haskell-prime mailing list
 

Re: In opposition of Functor as super-class of Monad

2012-10-24 Thread Duncan Coutts
On 24 October 2012 11:16, S. Doaitse Swierstra doai...@swierstra.net wrote:
 There are very good reasons for not following this road; indeed everything 
 which is a Monad can also be made an instance of Applicative. But more often 
 than not we want to have a more specific implementation. Because Applicative 
 is less general, there is in general more that you can do with it.

I don't think anyone is suggesting that we force all type that are
both Monad and Applicative to use (*)  = ap as the implementation.
As you say, that'd be crazy.

The details and differences between the various superclass proposals
are to do with how you provide the explicit instance vs getting the
default.

The wiki page explains it and links to the other similar proposals:

http://hackage.haskell.org/trac/ghc/wiki/DefaultSuperclassInstances

Duncan

___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Re: In opposition of Functor as super-class of Monad

2012-10-24 Thread Ben Franksen
First, let me make it clear that nowadays we are of course (I hope!) talking 
about making not only Functor, but Applicative a super-class of Monad (so 
Functor becomes a super-class by transitivity).

Petr P wrote:
 The main objections were that it would break existing code and that it
 would lead to code duplication. The former is serious, [...]
 
 To address the first objection:

I don't buy this it breaks lots of code argument. Adding the missing 
instances is a complete no-brainer; as you wrote:

 instance Applicative ... where
 pure   = return
 (*)  = ap
 instance Functor ... where
 fmap   = liftM

I do not think it is unreasonable to expect people to add such a simple and 
practically automatic fix to some old programs in the interest of cleaning 
up an old wart (and almost everyone agrees that this would be a good thing, 
in principle).

BTW, I guess most programs already contain the Functor instances (but maybe 
not Applicative, as it is newer).

I agree with Petr Pudlak that code duplication is not an issue, see above. 
And yes, these automatic instances may have stronger super-class 
constraints than strictly necessary. So what? The program didn't need the 
Functor (or Applicative) instance anyway (or it already would have defined 
it, in which case no change would be needed at all).

Default superclass instances strike me as a complicated proposal for 
solving trivial problems. The switch in Control.Exception (from data 
Exception to class Exception) was much more disrupting, adapting programs 
meant lots of changes everywhere exceptions are handled, not just adding 
some trivial instances. Still people managed the transition.

Cheers
-- 
Ben Franksen
()  ascii ribbon campaign - against html e-mail 
/\  www.asciiribbon.org   - against proprietary attachments


___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Re: In opposition of Functor as super-class of Monad

2012-10-24 Thread Tony Morris
I should hope not. The identity element (return, coreturn, mempty, pure,
Category.id) is almost never needed.

* http://hackage.haskell.org/package/semigroupoids
* https://gist.github.com/3871764



On 25/10/12 04:49, Ben Franksen wrote:
 First, let me make it clear that nowadays we are of course (I hope!) talking 
 about making not only Functor, but Applicative a super-class of Monad (so 
 Functor becomes a super-class by transitivity).

 Petr P wrote:
 The main objections were that it would break existing code and that it
 would lead to code duplication. The former is serious, [...]

 To address the first objection:
 I don't buy this it breaks lots of code argument. Adding the missing 
 instances is a complete no-brainer; as you wrote:

 instance Applicative ... where
 pure   = return
 (*)  = ap
 instance Functor ... where
 fmap   = liftM
 I do not think it is unreasonable to expect people to add such a simple and 
 practically automatic fix to some old programs in the interest of cleaning 
 up an old wart (and almost everyone agrees that this would be a good thing, 
 in principle).

 BTW, I guess most programs already contain the Functor instances (but maybe 
 not Applicative, as it is newer).

 I agree with Petr Pudlak that code duplication is not an issue, see above. 
 And yes, these automatic instances may have stronger super-class 
 constraints than strictly necessary. So what? The program didn't need the 
 Functor (or Applicative) instance anyway (or it already would have defined 
 it, in which case no change would be needed at all).

 Default superclass instances strike me as a complicated proposal for 
 solving trivial problems. The switch in Control.Exception (from data 
 Exception to class Exception) was much more disrupting, adapting programs 
 meant lots of changes everywhere exceptions are handled, not just adding 
 some trivial instances. Still people managed the transition.

 Cheers


-- 
Tony Morris
http://tmorris.net/



___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Re: In opposition of Functor as super-class of Monad

2012-10-24 Thread Ben Franksen
Tony Morris wrote:
 I should hope not. The identity element (return, coreturn, mempty, pure,
 Category.id) is almost never needed.
 
 * http://hackage.haskell.org/package/semigroupoids
 * https://gist.github.com/3871764

Off-topic. Feel free to start a new thread named The bombastic one-and-true 
class hierarchy I always wanted to have. These proposals have their merits, 
and I greatly respect the category theoretic knowledge that went into them 
-- but this is another discussion. This thread refers to a rather modest 
correction in the standard libraries, not a complete re-design. The idea is 
to fix something that is widely accepted as an unfortunate ommision (in 
fact, Oleg's comment is one of the very few that question the idea of adding 
super class constraints to Monad in principle).

BTW, it is unclear what your I hope not refers to, since in both of the 
hierarchies you linked to Applicative *is* a super class of Monad.

Cheers

 On 25/10/12 04:49, Ben Franksen wrote:
 First, let me make it clear that nowadays we are of course (I hope!) 
talking 
 about making not only Functor, but Applicative a super-class of Monad (so 
 Functor becomes a super-class by transitivity).

 Petr P wrote:
 The main objections were that it would break existing code and that it
 would lead to code duplication. The former is serious, [...]

 To address the first objection:
 I don't buy this it breaks lots of code argument. Adding the missing 
 instances is a complete no-brainer; as you wrote:

 instance Applicative ... where
 pure   = return
 (*)  = ap
 instance Functor ... where
 fmap   = liftM
 I do not think it is unreasonable to expect people to add such a simple 
and 
 practically automatic fix to some old programs in the interest of 
cleaning 
 up an old wart (and almost everyone agrees that this would be a good 
thing, 
 in principle).

 BTW, I guess most programs already contain the Functor instances (but 
maybe 
 not Applicative, as it is newer).

 I agree with Petr Pudlak that code duplication is not an issue, see 
above. 
 And yes, these automatic instances may have stronger super-class 
 constraints than strictly necessary. So what? The program didn't need the 
 Functor (or Applicative) instance anyway (or it already would have 
defined 
 it, in which case no change would be needed at all).

 Default superclass instances strike me as a complicated proposal for 
 solving trivial problems. The switch in Control.Exception (from data 
 Exception to class Exception) was much more disrupting, adapting programs 
 meant lots of changes everywhere exceptions are handled, not just adding 
 some trivial instances. Still people managed the transition.

 Cheers
 
 

-- 
Ben Franksen
()  ascii ribbon campaign - against html e-mail 
/\  www.asciiribbon.org   - against proprietary attachments


___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Re: In opposition of Functor as super-class of Monad

2011-01-05 Thread Isaac Dupree
Tony, you're missing the point... Alexey isn't making a complete patch 
to GHC/base libraries, just a hacky-looking demonstration.  Alexey is 
saying that in a class hierarchy (such as if Functor = Monad were a 
hierarchy, or for that matter XFunctor=XMonad or Eq = Ord), it is 
still possible to define the superclass functions (fmap) in terms of the 
subclass functions (return and =) (such as writing a functor instance 
in which fmap f m = m = (return . f)).  This has always been true in 
Haskell, it just might not have been obvious.


___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Re: In opposition of Functor as super-class of Monad

2011-01-05 Thread Tony Morris
On 06/01/11 04:58, Isaac Dupree wrote:
 Tony, you're missing the point... Alexey isn't making a complete patch
 to GHC/base libraries, just a hacky-looking demonstration.  Alexey is
 saying that in a class hierarchy (such as if Functor = Monad were a
 hierarchy, or for that matter XFunctor=XMonad or Eq = Ord), it
 is still possible to define the superclass functions (fmap) in terms
 of the subclass functions (return and =) (such as writing a functor
 instance in which fmap f m = m = (return . f)).  This has always
 been true in Haskell, it just might not have been obvious.

 ___
 Haskell-prime mailing list
 Haskell-prime@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-prime
Oh right sorry. I thought a stronger point was being made.

Then perhaps it's also worth pointing out that (*) can be written
using (=) and return:
f * a = f = \ff - a = \aa - return (ff aa)

-- 
Tony Morris
http://tmorris.net/



___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Re: In opposition of Functor as super-class of Monad

2011-01-05 Thread Iavor Diatchki
Hi,
indeed, this is called ap in Control.Monad.  So if we have an instance of
Monad, all that needs to be done to support the other instances is:

instance (SameContextAsTheMonadInstance) = Functor MyType where fmap =
liftM
instance (SameContextAsTheMonadInstance) = Applicative MyType where pure =
return; (*) = ap

Furthermore, this is only in the cases where we are defining the type from
scratch, and not using a library like monadLib or MTL, otherwise a simple
deriving is sufficient.

-Iavor

On Wed, Jan 5, 2011 at 12:29 PM, Tony Morris tonymor...@gmail.com wrote:

 On 06/01/11 04:58, Isaac Dupree wrote:
  Tony, you're missing the point... Alexey isn't making a complete patch
  to GHC/base libraries, just a hacky-looking demonstration.  Alexey is
  saying that in a class hierarchy (such as if Functor = Monad were a
  hierarchy, or for that matter XFunctor=XMonad or Eq = Ord), it
  is still possible to define the superclass functions (fmap) in terms
  of the subclass functions (return and =) (such as writing a functor
  instance in which fmap f m = m = (return . f)).  This has always
  been true in Haskell, it just might not have been obvious.
 
  ___
  Haskell-prime mailing list
  Haskell-prime@haskell.org
  http://www.haskell.org/mailman/listinfo/haskell-prime
 Oh right sorry. I thought a stronger point was being made.

 Then perhaps it's also worth pointing out that (*) can be written
 using (=) and return:
 f * a = f = \ff - a = \aa - return (ff aa)

 --
 Tony Morris
 http://tmorris.net/



 ___
 Haskell-prime mailing list
 Haskell-prime@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-prime

___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


In opposition of Functor as super-class of Monad

2011-01-04 Thread oleg

I'd like to argue in opposition of making Functor a super-class of
Monad. I would argue that superclass constraints are not the right
tool for expressing mathematical relationship such that all monads are
functors and applicatives.

Then argument is practical. It seems that making Functor a superclass
of Monad makes defining new monad instances more of a chore, leading
to code duplication. To me, code duplication is a sign that an
abstraction is missing or misused.

For the sake of the argument, let us suppose that Functor is a
superclass of Monad. Let us see how to define a new Monad
instance. For the sake of a better illustration, I'll use a complex
monad. I just happen to have an example of that: Iteratee.
The data type Iteratee is defined as follows:

 type ErrMsg = String-- simplifying
 data Stream el = EOF (Maybe ErrMsg) | Chunk [el] deriving Show

 data Iteratee el m a = IE_done a
  | IE_cont (Maybe ErrMsg)
(Stream el - m (Iteratee el m a, Stream el))
   

We wish to define an instance for Monad (Iteratee el m). Since Functor
is a superclass of Monad, we must define a functor instance:

 instance Functor m = Functor (Iteratee el m) where
 fmap f (IE_done a)   = IE_done (f a)
 fmap f (IE_cont e k) = IE_cont e (\s - fmap docase (k s))
  where
  docase (IE_done a,s) = (IE_done (f a), s)
  docase (i, s)= (fmap f i, s)

There are two ways to proceed with the Monad instance -- to be
precise, there are two ways of defining bind.

Method A: just define bind as usual

 instance (Functor (Iteratee el m),Monad m) = Monad (Iteratee el m) where
 return = IE_done

 IE_done a   = f = f a
 IE_cont e k = f = IE_cont e (\s - k s = docase)
  where
  docase (IE_done a, stream)   = case f a of
  IE_cont Nothing k - k stream
  i - return (i,stream)
  docase (i, s)  = return (i = f, s)

Although we must state the constraint (Functor (Iteratee el m)) to
satisfy the super-class constraint, we have not made any use of the
constraint. We defined bind without resorting to fmap. That seems like
a waste. What makes it seem more like a waste is that the code for
fmap and for bind is almost the same. We had to repeat essentially the
same algorithm, analysing Iteratee and the continuation.

Method B: define bind in terms of fmap

Alas, just fmap is not sufficient to define bind. We need join:

 joinIter :: Monad m = Iteratee el m (Iteratee el m a) - Iteratee el m a
 joinIter (IE_done i) = i
 joinIter (IE_cont e k) = IE_cont e (\s - k s = docase)
  where
  docase (IE_done (IE_cont Nothing k), s) = k s
  docase (IE_done i, s)   = return (i, s)
  docase (i, s)   = return (joinIter i, s)

Only after defining join we can write

 bind m f = joinIter $ fmap f m

Again we see code duplication: the code for join resembles the code
for fmap. The code for join follows the same pattern of analysing
Iteratee and the continuation.

In either way, Functor as a super-class of Monad leads to code
duplication. That gives a bad feeling practically -- and
theoretically. The experiment has led me wonder if a superclass
constraint is the right way to state the relationship between Monads
and Functors.

It _almost_ makes me wish the constraint go the other way:

 instance Monad m = Functor m where
   fmap f m = m = (return . f)

That is, we need an instance rather than a superclass constraint, and
in the other direction. The instance constraint says that every monad
is a functor. Moreover,
\f m = m = (return . f)

is a _proof term_ that every monad is a functor. We can state it once
and for all, for all present and future monads.

Alas, the instance ``instance Monad m = Functor m'' above has several
drawbacks (for one, requiring overlapping instances everywhere). This
makes me wonder if something is amiss.

In the meanwhile, there is a practical work-around. Introduce a
TemplateHaskell operation generating an instance such as

 instance Monad (Iteratee el m) = Functor (Iteratee el m) where
   fmap f m = m = (return . f)

(the code for the method remains the same; only the type in the
instance head varies). Alas, that requires undecidable instances. All
the code before was Haskell98.



___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Re: In opposition of Functor as super-class of Monad

2011-01-04 Thread Martijn van Steenbergen

Method C: Define fmap in terms of bind


instance Monad m = Functor (Iteratee el m) where
  fmap = liftM


Now you need to do the inspection of Iteratee only once: in the 
definition of the bind. However, to use liftM as implementation of fmap 
the superclass constraint of the Functor instance has changed from 
Functor to Monad.


Is this a problem? If so, method A seems the way to go: you could argue 
that `Functor m = fmap :: (a - b) - Iteratee el m a - Iteratee el m 
b' is more general than the `Monad m =' version (works for more `m's) 
and therefore deserves to redo the analysis of Iteratee.


Martijn.


On 1/4/11 11:24, o...@okmij.org wrote:

I'd like to argue in opposition of making Functor a super-class of
Monad. I would argue that superclass constraints are not the right
tool for expressing mathematical relationship such that all monads are
functors and applicatives.


___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Re: In opposition of Functor as super-class of Monad

2011-01-04 Thread Dan Doel
On Tuesday 04 January 2011 5:24:21 am o...@okmij.org wrote:
 Method A: just define bind as usual
 
  instance (Functor (Iteratee el m),Monad m) = Monad (Iteratee el m) where
  
  return = IE_done
  
  IE_done a   = f = f a
  IE_cont e k = f = IE_cont e (\s - k s = docase)
  
   where
   docase (IE_done a, stream)   = case f a of
   
   IE_cont Nothing k - k stream
   i - return (i,stream)
   
   docase (i, s)  = return (i = f, s)
 
 Although we must state the constraint (Functor (Iteratee el m)) to
 satisfy the super-class constraint, we have not made any use of the
 constraint.

This, at least, is false. If Functor is a superclass of Monad, then Monad m 
implies Functor m, which implies Functor (Iteratee el m). So Monad m is a 
sufficient constraint for the instance.

As for the other concerns, I think the closest fix I've seen is to allow 
subclasses to specify defaults for superclasses, and allow instances for 
subclasses to include methods for superclasses. So:

  class Functor m = Monad m where
return :: a - m a
(=)  :: m a - (a - m b) - m b

fmap f x = x = return . f

This has its own caveats of course. And in this case, it seems to 
overconstrain the functor instance, since presumably we'd end up with:

  instance Monad m = Monad (Iteratee el m) where ...
==
  instance Monad m = Functor (Iterate el m) where ...

I'm not sure what to do about that.

-- Dan

___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Re: In opposition of Functor as super-class of Monad

2011-01-04 Thread Alexey Khudyakov

On 04.01.2011 13:24, o...@okmij.org wrote:


I'd like to argue in opposition of making Functor a super-class of
Monad. I would argue that superclass constraints are not the right
tool for expressing mathematical relationship such that all monads are
functors and applicatives.

Then argument is practical. It seems that making Functor a superclass
of Monad makes defining new monad instances more of a chore, leading
to code duplication. To me, code duplication is a sign that an
abstraction is missing or misused.




I think I understood your point. But it looks like that it's possible to 
use subclass's function in superclass instance. At very least GHC is 
able to do it.


Following example works just fine without any language extensions in 
GHC6.12.3



import Prelude hiding (Monad(..), Functor(..))

class Functor f where
  fmap :: (a - b) - f a - f b

class Functor m = Monad m where
  return :: a - m a
  (=) :: m a - (a - m b) - m b

instance Functor Maybe where
  fmap f m = m = (return . f)
instance Monad Maybe where
  return = Just
  Nothing = _ = Nothing
  Just x  = f = f x

___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Re: In opposition of Functor as super-class of Monad

2011-01-04 Thread Tony Morris
I think you'll find a problem using do-notation with your Monad.

Tony Morris

On 04/01/2011 11:33 PM, Alexey Khudyakov alexey.sklad...@gmail.com
wrote:

On 04.01.2011 13:24, o...@okmij.org wrote:


 I'd like to argue in opposition of making Functor a...
I think I understood your point. But it looks like that it's possible to use
subclass's function in superclass instance. At very least GHC is able to do
it.

Following example works just fine without any language extensions in
GHC6.12.3


import Prelude hiding (Monad(..), Functor(..))

class Functor f where
 fmap :: (a - b) - f a - f b



class Functor m = Monad m where
 return :: a - m a
 (=) :: m a - (a - m b) - m b
instance Functor Maybe where


 fmap f m = m = (return . f)
instance Monad Maybe where
 return = Just
 Nothing = _ = Nothing
 Just x  = f = f x



___
Haskell-prime mailing list
haskell-pr...@haskell.o...
___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Re: In opposition of Functor as super-class of Monad

2011-01-04 Thread kahl
On Tue, Jan 04, 2011 at 02:24:21AM -0800, o...@okmij.org wrote:
  
  I'd like to argue in opposition of making Functor a super-class of
  Monad. I would argue that superclass constraints are not the right
  tool for expressing mathematical relationship such that all monads are
  functors and applicatives.
  
  Then argument is practical. It seems that making Functor a superclass
  of Monad makes defining new monad instances more of a chore, leading
  to code duplication. To me, code duplication is a sign that an
  abstraction is missing or misused.

The argument about code duplication somehow seems to assume that
class member instances need to be defined as part of the instance
declaration. This is not the case, and in fact I am arguing in general
against putting any interesting code into instance declarations,
especially into declarations of instances with constraints
(since, in ML terminology, they are functors, and putting their
definition inside an instance declaration constrains their applicability).

In my opinion, the better approach is to define (generalised versions of)
the functions mentioned in the class interface,
and then just throw together the instances from those functions.
This also makes it easier to adapt to the ``class hierarchy du jour''.

The point for the situation here is that although we eventually need
definitions of all the functions declared as class members,
there is absolutely nothing that constrains the dependency relation
between the definitions of these functions to be conforming in any way
to the class hierarchy.

For a simpler example, assume that I have some arbitrary data type

 data T a = One a | Two a a

and assume that I am interested only in Ord instances, since I want to
use T with Data.Set, and I am not really interested in Eq instances.

Assume that the order will depend on that for |a|,
so I will define a function:

 compareT :: (a - a - Ordering) - T a - T a - Ordering

Then I can thow together the necessary instances from that:

 instance Ord a = Ord (T a) where
   compare = compareT compare
 
 instance Ord a = Eq (T a) where
   (==) = eqFromCompare compare

assuming I have (preferably from the exporter of Eq and Ord):

 eqFromCompare :: (a - a - Ordering) - (a - a - Bool)
 eqFromCompare cmp x y = case cmp x y of
   EQ - True
   _ - False

The same approach works for Oleg's example:

  For the sake of the argument, let us suppose that Functor is a
  superclass of Monad. Let us see how to define a new Monad
  instance. For the sake of a better illustration, I'll use a complex
  monad. I just happen to have an example of that: Iteratee.
  The data type Iteratee is defined as follows:

 type ErrMsg = String-- simplifying
 data Stream el = EOF (Maybe ErrMsg) | Chunk [el] deriving Show

 data Iteratee el m a = IE_done a
  | IE_cont (Maybe ErrMsg)
(Stream el - m (Iteratee el m a, Stream el))

  [...]   
  
  It _almost_ makes me wish the constraint go the other way:
  
   instance Monad m = Functor m where
  fmap f m = m = (return . f)
  
  That is, we need an instance rather than a superclass constraint, and
  in the other direction. The instance constraint says that every monad
  is a functor. Moreover,
   \f m = m = (return . f)
  
  is a _proof term_ that every monad is a functor. We can state it once
  and for all, for all present and future monads.

I would expect that proof term to exported by the package exporting
Functor and Monad; let us define it here:

 fmapFromBind (=) f m = m = (return . f)

Now you can write, no matter which class is a superclass of which:

 bindIt return (=) (IE_done a) f = f a
 bindIt return (=) (IE_cont e k) f = IE_cont e (\s - k s = docase)
   where
 docase (IE_done a, stream)   = case f a of
   IE_cont Nothing k - k stream
   i - return (i,stream)
 docase (i, s)  = return (bindIt return (=) i f, s)
 
 instance Monad m = Monad (Iteratee el m) where
return = IE_done
(=) = bindIt return (=)
 
 instance Monad m = Functor (Iteratee el m) where
   fmap = fmapFromBind (=)

Of course this assumes that you are not actually interested in an
instance of shape: instance (Functor ...) = Functor (Iteratee el m),
but this seems to be a plausible assumption.

Defining the functionality really has nothing to do with declaring an
instance of a type class, and it is normally better to keep the two
separated. And that does not lead to any real code duplication,
only extremely boring instance declarations.


Wolfram



___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime