A general question about the use of classes in defining interfaces

Stimulated by remarks made during the discussion on the future of  
Haskell at the last Haskell Symposium, I have started to convert my  
new parsing library (constructed for the Lernet summerschool in  
Uruguay) into Cabalised form. In this library I have amongst others  
the class:

class  Applicative p where
  (<*>)     ::   p (b -> a)  -> p b   ->   p a
  (<|>)     ::   p a         -> p a   ->   p a
  (<$>)     ::   (b -> a)    -> p b   ->   p a
  pReturn   ::   a                    ->   p a
  pFail     ::                             p a
  f <$> p   =  pReturn f <*> p

which extends/deviates from the standard class Applicative, since I  
think these functions more or less belong together. I am happy to  
factor out <|> into a separate class.

The problem which arises now is when I want to use the class  
Applicative as it is now defined in Control.Applicative. Functions  
like <$>, <$, <* and many have standard implementations in terms of  
the basic function pure and <*>. Although this looks fine at first  
sight, this is not so fine if we want to give more specialised  
(optimised, checking) implementations, as I am doing in my library. An  
example of this is e.g. in many, where I want to check that the  
parameter parser does not recognise the empty sequence since thi is  
non-sense, etc. Of course we can describe <* by

p <* q = pure const <*> p <*> q

(Continue reading)

Henrik Nilsson | 8 Oct 14:26

Re: A general question about the use of classes in defining interfaces

Hi Doaitse, Ross,

Doaitse wrote:

 > The problem which arises now is when I want to use the class
 > Applicative as it is now defined in Control.Applicative. Functions
 > like <$>, <$, <* and many have standard implementations in terms of
 > the basic function pure and <*>. Although this looks fine at first
 > sight, this is not so fine if we want to give more specialised
 > (optimised, checking) implementations, as I am doing in my library.

There used to be the same problem with the Arrow class, with
operators like &&& and *** having standard definitions, but not
being redefineable due to not being class methods, which prevented
(or at least made much more difficult) certain optimizations.

After some prodding from me, Ross moved them into the Arrow class,
with default definitions.

I was and still am quite happy with that, and I'm not aware of
any major drawbacks, except that it might not be so clear
exactly where to draw the line between methods and top-level
standard definitions if one opt to include more than the bare
minimum of methods.

Best,

/Henrik

--

-- 
(Continue reading)


Gmane