Re: [Haskell-cafe] type class design

2010-12-21 Thread Jean-Marie Gaillourdet
Hi,

sorry for answering to such an old thread.

David Menendez d...@zednenem.com writes:

 On Fri, Oct 29, 2010 at 8:33 AM, Tillmann Rendel
 ren...@informatik.uni-marburg.de wrote:
 Hi,

 Uwe Schmidt wrote:

 In the standard Haskell classes we can find both cases,
 even within a single class.

 Eq with (==) as f and (/=) as g belongs to the 1. case

 Note that the case of (==) and (/=) is slightly different, because not only
 can (/=) be defined in terms (==), but also the other way around. The
 default definitions of (==) and (/=) are mutually recursive, and trivially
 nonterminating. This leaves the choice to the instance writer to either
 implement (==) or (/=). Or, for performance reasons, both.

 While I understand the argument in general, I've never understood why
 it applies to Eq. Are there any types where it is preferable to define
 (/=) instead of (==)?

Yes for infinite data structures.

Cheers,
  Jean-Marie


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


Re: [Haskell-cafe] type class design

2010-12-21 Thread David Menendez
On Tue, Dec 21, 2010 at 4:30 AM, Jean-Marie Gaillourdet
j...@gaillourdet.net wrote:
 Hi,

 sorry for answering to such an old thread.

 David Menendez d...@zednenem.com writes:

 On Fri, Oct 29, 2010 at 8:33 AM, Tillmann Rendel
 ren...@informatik.uni-marburg.de wrote:
 Hi,

 Uwe Schmidt wrote:

 In the standard Haskell classes we can find both cases,
 even within a single class.

 Eq with (==) as f and (/=) as g belongs to the 1. case

 Note that the case of (==) and (/=) is slightly different, because not only
 can (/=) be defined in terms (==), but also the other way around. The
 default definitions of (==) and (/=) are mutually recursive, and trivially
 nonterminating. This leaves the choice to the instance writer to either
 implement (==) or (/=). Or, for performance reasons, both.

 While I understand the argument in general, I've never understood why
 it applies to Eq. Are there any types where it is preferable to define
 (/=) instead of (==)?

 Yes for infinite data structures.

How so?

For an infinite structure, x == y will return False or not return and
x /= y will return True or not return. We still have x /= y = not (x
== y) and I don't see any reason why one would prefer to define (/=)
instead of (==).

-- 
Dave Menendez d...@zednenem.com
http://www.eyrie.org/~zednenem/

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


Re: [Haskell-cafe] type class design

2010-10-31 Thread Ivan Lazar Miljenovic
On 30 October 2010 22:44, Uwe Schmidt u...@fh-wedel.de wrote:
 Another possible argument: large type classes can look daunting for
 both implementors and users, even if only one or two methods need to
 be defined for a minimal instantiation (I'm tring to work out what to
 do here myself, as I have some typeclasses that for efficiency reasons
 it might be nice to have more methods in the class, but it makes it a
 little overwhelming).

 But by putting just a small part of the interface into the class
 does not make the live of a user any simpler.
 The user usually has to know the whole interface of the module.
 Or am I missing something?

Well, if you have a small class then it's possible for you to split up
the different types of functions to be in different modules into more
logical sub-types, etc.

Also, I find the documentation for the list functions in the Prelude
and Data.List easier to read than the ones in ListLike [1], partially
because typical documentation for class methods is typically smaller
and more compact than the stand-alone functions.

[1]: http://hackage.haskell.org/package/ListLike

-- 
Ivan Lazar Miljenovic
ivan.miljeno...@gmail.com
IvanMiljenovic.wordpress.com
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] type class design

2010-10-30 Thread Uwe Schmidt
Hi Ivan,

 Another possible argument: large type classes can look daunting for
 both implementors and users, even if only one or two methods need to
 be defined for a minimal instantiation (I'm tring to work out what to
 do here myself, as I have some typeclasses that for efficiency reasons
 it might be nice to have more methods in the class, but it makes it a
 little overwhelming).

But by putting just a small part of the interface into the class
does not make the live of a user any simpler.
The user usually has to know the whole interface of the module.
Or am I missing something?

Cheers,

  Uwe
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] type class design

2010-10-29 Thread Uwe Schmidt
Dear Haskellers,

I've a question about type class design. When
developing the set of functions for a class, there
are often two or more functions, let's say f and g,
where the semantics of g can be expressed by f.

When writing down the code, there are two choices
for g. First g is included in the type class, second
g is defined outside and the signature has a context
referencing the class.

1. case

class Foo a where
  f :: ... a ...
  g :: ... a ...
  g = expr[f]

2. case

class Foo a where
  f :: ... a ...

g :: Foo a = ... a ...
g = expr[f]


What are the reasons for choosing 1., what are the arguments for 2.?

My arguments for 1.:

a) Efficiency: g may be overwritten in an instance declaration
  by a more efficient piece of code.

b) Readability: All functions, which are logically connected
  are grouped together in a single syntactic construct and
  can be found in one place (similar to an interface in Java).

My argument for 2.:

c) Correctness: The semantics for g are fix (relative to f),
  All laws for g hold everywhere, assuming f is implemented
  correctly.

I've sometimes the problem to balance the reasons for 1. and
2 and I doubt, that this list of criteria is complete.

In the standard Haskell classes we can find both cases,
even within a single class.

Eq with (==) as f and (/=) as g belongs to the 1. case, so does
Monad and (=) as f and () as g.
But (=) and the Monad class fall into
the 2. case. It seem, there is no uniform
or consistent strategy in the core Haskell classes.

What are your best practice rules for this problem?

Expecting your advices,

  Uwe

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


Re: [Haskell-cafe] type class design

2010-10-29 Thread Tillmann Rendel

Hi,

Uwe Schmidt wrote:

In the standard Haskell classes we can find both cases,
even within a single class.

Eq with (==) as f and (/=) as g belongs to the 1. case


Note that the case of (==) and (/=) is slightly different, because not 
only can (/=) be defined in terms (==), but also the other way around. 
The default definitions of (==) and (/=) are mutually recursive, and 
trivially nonterminating. This leaves the choice to the instance writer 
to either implement (==) or (/=). Or, for performance reasons, both.


  Tillmann
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] type class design

2010-10-29 Thread Ivan Lazar Miljenovic
On 29 October 2010 23:28, Uwe Schmidt u...@fh-wedel.de wrote:
 Dear Haskellers,

 I've a question about type class design. When
 developing the set of functions for a class, there
 are often two or more functions, let's say f and g,
 where the semantics of g can be expressed by f.

 When writing down the code, there are two choices
 for g. First g is included in the type class, second
 g is defined outside and the signature has a context
 referencing the class.

 1. case

 class Foo a where
  f :: ... a ...
  g :: ... a ...
  g = expr[f]

 2. case

 class Foo a where
  f :: ... a ...

 g :: Foo a = ... a ...
 g = expr[f]

 [snip]

 My argument for 2.:

 c) Correctness: The semantics for g are fix (relative to f),
  All laws for g hold everywhere, assuming f is implemented
  correctly.

Another possible argument: large type classes can look daunting for
both implementors and users, even if only one or two methods need to
be defined for a minimal instantiation (I'm tring to work out what to
do here myself, as I have some typeclasses that for efficiency reasons
it might be nice to have more methods in the class, but it makes it a
little overwhelming).

-- 
Ivan Lazar Miljenovic
ivan.miljeno...@gmail.com
IvanMiljenovic.wordpress.com
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] type class design

2010-10-29 Thread Ben Millwood
On Fri, Oct 29, 2010 at 1:33 PM, Tillmann Rendel
ren...@informatik.uni-marburg.de wrote:

 Note that the case of (==) and (/=) is slightly different, because not only
 can (/=) be defined in terms (==), but also the other way around. The
 default definitions of (==) and (/=) are mutually recursive, and trivially
 nonterminating. This leaves the choice to the instance writer to either
 implement (==) or (/=). Or, for performance reasons, both.


I find these sorts of defaults deeply unsatisfying: particularly, suppose I do

newtype Foo = Foo Integer
  deriving (Eq, Show)

instance Num Foo where
  Foo a + Foo b = Foo (a + b)
  fromInteger = Foo

expr = Foo 3 - Foo 2

That I haven't defined implementations for (-) or negate will not even
get me a compiler warning, let alone a static error: it will just
stack overflow or spin endlessly on expr. This kind of bug is
notoriously difficult to track down.

I'm not sure how to handle this better, though. A compiler that
automatically calculated minimal complete definitions would be nice,
but relatively complicated. It might be more sensible to just take all
efficiency methods out of classes, and use a mechanism like rewrite
rules to give an efficient implementation where possible.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] type class design

2010-10-29 Thread David Menendez
On Fri, Oct 29, 2010 at 8:33 AM, Tillmann Rendel
ren...@informatik.uni-marburg.de wrote:
 Hi,

 Uwe Schmidt wrote:

 In the standard Haskell classes we can find both cases,
 even within a single class.

 Eq with (==) as f and (/=) as g belongs to the 1. case

 Note that the case of (==) and (/=) is slightly different, because not only
 can (/=) be defined in terms (==), but also the other way around. The
 default definitions of (==) and (/=) are mutually recursive, and trivially
 nonterminating. This leaves the choice to the instance writer to either
 implement (==) or (/=). Or, for performance reasons, both.

While I understand the argument in general, I've never understood why
it applies to Eq. Are there any types where it is preferable to define
(/=) instead of (==)?

-- 
Dave Menendez d...@zednenem.com
http://www.eyrie.org/~zednenem/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe