[Haskell-cafe] Re: Re: Hit a wall with the type system

Chris Smith cdsmith at twu.net
Thu Nov 29 15:58:15 EST 2007

Dan Piponi wrote:
> I must be missing the point of something. What's wrong with
> > diff f x = let AD y dy = f (AD x 1) in dy
> ?
> In ghci we get
> *Main> :t diff (\x -> 2*x) (2::Int)
> diff (\x -> 2*x) (2::Int) :: Int
> *Main> :t diff (\x -> 2*x) (2::Float)
> diff (\x -> 2*x) (2::Float) :: Float
> I've used almost exactly that line of code myself a few times.

Yep, that does what I want.  Thank you (and Stefan, and ghci's :t) for 
pointing it out.  If this were a practical thing, I'd certainly decide 
that's the best option and move on.  But since this is me trying to 
figure out the Right Answer (tm), that still doesn't look like it.  
(Though I suspect if there were a Right Answer, it would have been 
pointed out by now.)

>From my perspective, what's wrong with it what Stefan mentioned when he 
suggested it: it breaks abstraction.  Even if I don't expose the type AD 
(i.e., it's an implementation detail and the user of a library shouldn't 
care that it even exists), the inferred type signature for diff depends 
on it.

  Prelude AD> :t diff
  diff :: forall a t. (Num a) => (AD.AD a -> AD.AD t) -> a -> t

But what's AD?  If it's exported, then at least it will show up in 
Haddock with a list of its instances, so the type is merely misleading.  
but if it's not exported, then the type is just plain not useful.

So I want the parameter to be more restricted.  No one is going to write 
a function that *only* works on AD types.  Instead, the parameter to 
diff ought to be required to be polymorphic.  The rank n type does that, 
but it loses the ability to get the most general possible result type.

Chris Smith

More information about the Haskell-Cafe mailing list