[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