#1696: Confusing type signature
----------------------------------------+-----------------------------------
    Reporter:  guest                    |        Owner:         
        Type:  bug                      |       Status:  new    
    Priority:  low                      |    Milestone:  _|_    
   Component:  Compiler (Type checker)  |      Version:  6.6.1  
    Severity:  trivial                  |   Resolution:         
    Keywords:                           |   Difficulty:  Unknown
          Os:  Unknown                  |     Testcase:         
Architecture:  Unknown                  |  
----------------------------------------+-----------------------------------
Changes (by simonpj):

  * component:  Compiler => Compiler (Type checker)
  * milestone:  => _|_
  * priority:  normal => low

Old description:

> I was working with some buggy numerical code of mine, and I was having
> problems with some types involving exponentiation. My working hypothesis
> was that the problem involved using ^ with a numerical type I had defined
> - I had checked ^'s type through :t and saw:
> {{{
>  (^) :: forall a b. (Integral b, Num a) => a -> b -> a
> }}}
> I immediately thought that I needed another type class declaration for my
> new type, and went haring off on that tangent for a long time. Eventually
> someone on #haskell pointed out to me that the *base* could be Num, but
> the power to which it was being raised had to be Integral and that my
> problems stemmed from going foo^(1/3), and that what I needed was more
> along the lines of foo**(1/3).
>
> My confusion stemmed from the variables - the forall declaration goes, in
> order, a-b, and the curried signature itself goes a-b as well, but the
> classes goes b-a! This apparently is for no particular reason, and so I
> think it'd be good if the signatures :t displayed could be a little more
> consistent and go a-b as well, so it'd be instead:
> {{{
>  (^) :: forall a b. (Num a, Integral b) => a -> b -> a
> }}}
> A small thing, perhaps, but it did trip me up.

New description:

 I was working with some buggy numerical code of mine, and I was having
 problems with some types involving exponentiation. My working hypothesis
 was that the problem involved using `(^)` with a numerical type I had
 defined - I had checked `(^)`'s type through :t and saw:
 {{{
  (^) :: forall a b. (Integral b, Num a) => a -> b -> a
 }}}
 I immediately thought that I needed another type class declaration for my
 new type, and went haring off on that tangent for a long time. Eventually
 someone on #haskell pointed out to me that the *base* could be Num, but
 the power to which it was being raised had to be Integral and that my
 problems stemmed from going foo^(1/3), and that what I needed was more
 along the lines of foo**(1/3).

 My confusion stemmed from the variables - the forall declaration goes, in
 order, a-b, and the curried signature itself goes a-b as well, but the
 classes goes b-a! This apparently is for no particular reason, and so I
 think it'd be good if the signatures :t displayed could be a little more
 consistent and go a-b as well, so it'd be instead:
 {{{
  (^) :: forall a b. (Num a, Integral b) => a -> b -> a
 }}}
 A small thing, perhaps, but it did trip me up.

Comment:

 Ah now I see.  When you say
 {{{
 :t (^)
 }}}
 GHC infers the type of the (rather small) expression `(^)`.  In doing so,
 it instantiates the function and re-generalises it.  That jumbles up the
 constraints.

 Random thoughts:
  * We could have a special case for `:t` of a single identifier, which
 simply prints the type of the identifier. That would be a bit of a hack,
 but would eliminate any jumbling in a common case.

  * When GHCi ''displays'' a type for the user, it drops the foralls, and
 combines constraints (actually this is a recent fix).  It could do more:
 it could re-order the constraints to look nicer.

  * Alternatively, when generalising, GHC could sort the constraints (and
 perhaps the type variables too) into a nicer order.  That would entail
 extra work that would usually go unseen; but perhaps it'd be worth it.

 I don't this this is very high priority, but I'm jotting down these notes
 so that we don't lose the thought.  Thanks for raising it.

 Simon

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/1696>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to