RealFloat constraint on Complex type

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

RealFloat constraint on Complex type

Conal Elliott
GHC's (maybe Haskell98's?) Complex type is defined with a RealFloat constraint on type type itself, rather than on some of the instances and functions:

    data (RealFloat a) => Complex a  = !a :+ !a

I think the practice of constraint in type definitions is generally discouraged, and I'm wondering if there are reasons other than history for having the constraint here.  Is removing it on the table for Haskell'?

I just got bit by what I think is a typical problem.  I added a VectorSpace instance for 'Complex a' and discovered that my 'a' must be in RealFloat, even though I use only zero, addition, subtraction, and scaling.

I suspect this gripe has been raised before ...

Thanks,  - Conal


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: RealFloat constraint on Complex type

Richard A. O'Keefe

On 21 May 2008, at 9:25 am, Conal Elliott wrote:
> I think the practice of constraint in type definitions is generally  
> discouraged,

Is this true?  If so, why?
If I have a data type that simply doesn't make sense unless some of the
type variables belong to certain classes, _shouldn't_ that be stated
clearly in the declaration rather than hidden elsewhere?

--
"I don't want to discuss evidence." -- Richard Dawkins, in an
interview with Rupert Sheldrake.  (Fortean times 232, p55.)






_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

RE: RealFloat constraint on Complex type

Bayley, Alistair-3
> From: [hidden email]
> [mailto:[hidden email]] On Behalf Of
> Richard A. O'Keefe
>
> On 21 May 2008, at 9:25 am, Conal Elliott wrote:
> > I think the practice of constraint in type definitions is
> generally  
> > discouraged,
>
> Is this true?  If so, why?
> If I have a data type that simply doesn't make sense unless
> some of the
> type variables belong to certain classes, _shouldn't_ that be stated
> clearly in the declaration rather than hidden elsewhere?


I recall this from Graham Klyne, but I think his use case might be a bit
different:

http://www.ninebynine.org/Software/Learning-Haskell-Notes.html#type-clas
ses-and-data

I don't know all the pros and cons (are there pros, other than the
documentation argument you gave?). I think:
 1. adding the constraint has some costs, and very few benefits
 2. nobody does it much, if at all. Probably for the first reason.

Alistair
*****************************************************************
Confidentiality Note: The information contained in this message,
and any attachments, may contain confidential and/or privileged
material. It is intended solely for the person(s) or entity to
which it is addressed. Any review, retransmission, dissemination,
or taking of any action in reliance upon this information by
persons or entities other than the intended recipient(s) is
prohibited. If you received this in error, please contact the
sender and delete the material from any computer.
*****************************************************************

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: RealFloat constraint on Complex type

Henning Thielemann
In reply to this post by Conal Elliott

On Tue, 20 May 2008, Conal Elliott wrote:

> GHC's (maybe Haskell98's?) Complex type is defined with a RealFloat
> constraint on type type itself, rather than on some of the instances and
> functions:
>
>    data (RealFloat a) => Complex a  = !a :+ !a
>
> I think the practice of constraint in type definitions is generally
> discouraged, and I'm wondering if there are reasons other than history for
> having the constraint here.  Is removing it on the table for Haskell'?
>
> I just got bit by what I think is a typical problem.  I added a VectorSpace
> instance for 'Complex a' and discovered that my 'a' must be in RealFloat,
> even though I use only zero, addition, subtraction, and scaling.
>
> I suspect this gripe has been raised before ...

Actually, in NumericPrelude there is no such constraint and Complex is an
instance of Module and VectorSpace:
   http://darcs.haskell.org/numericprelude/src/Number/Complex.hs
   http://hackage.haskell.org/cgi-bin/hackage-scripts/package/numeric-prelude
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: RealFloat constraint on Complex type

Bryan O'Sullivan
In reply to this post by Richard A. O'Keefe
Richard A. O'Keefe wrote:

>> I think the practice of constraint in type definitions is generally
>> discouraged,
>
> Is this true?  If so, why?

As a practical matter, a Haskell 98 constraint infects every place you
might like to use the type.  They're like prion proteins, corrupting
everything they touch, replicating implacably as they go.

Here's the usual pattern that leads to the abandonment of constraints on
types by the previously innocent coder.  You add the constraint in the
one place you think you need it, only to find that the type checker
insists that three more are now required on previously pristine code
that otherwise never mentions your type.  You reluctantly add the
constraint to those, and the compiler demands another seven uses.  Now
your code is littered with meaningless spaghetti constraints that
obfuscate your original intent.

The same contagion also costs you the ability to derive instances of
many useful built-in typeclasses, such as Functor.  The constraint on
the type requires that a function such as fmap must have the constraint,
too, and thus the plague continues.

Pre-GADT syntax doesn't have this problem.

  {-# LANGUAGE GADTs #-}

  data Foo a = Show a => Foo a

  foo :: Foo a -> a
  foo (Foo a) = a

Notice the change in the location of the constraint, and the lack of a
need for a constraint on the function foo.  Real GADTs avoid the problem
in a similar way.

  data Bar a where
      Bar :: Show a => a -> Bar a

  bar :: Bar a -> a
  bar (Bar a) = a
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe