Question

I'm having little success wrapping my head around the basic plumbing of the types involved in the ad package. For example, the following works perfectly:

import Numeric.AD

ex :: Num a => [a] -> a
ex [x, y] = x + 2*y

> grad ex [1.0, 1.0]
[1.0, 2.0]

where grad has the type:

grad
  :: (Num a, Traversable f) =>
     (forall (s :: * -> *). Mode s => f (AD s a) -> AD s a)
     -> f a -> f a

If I change the type signature of ex to [Double] -> Double and try the same thing, I get

Couldn't match expected type `AD s a0' with actual type `Double'
Expected type: f0 (AD s a0) -> AD s a0
  Actual type: [Double] -> Double

The same behaviour occurs when replacing Double with seemingly any type constructor with kind * that instantiates Num.

When the Traversable f is a list, the first argument of grad must have type [AD s a] -> AD s a for some acceptable Mode - e.g., Reverse. But clearly the user of grad doesn't have to deal with the AD constructor or the Mode directly. Peeking into these internals have left me a bit confused; specifically, I can't follow the kind/type trail to the difference between using Num a => [a] -> a and [Double] -> Double.

Why does the type signature [Double] -> Double cause problems with grad? And in terms of plain old library use: is there any way to use the [Double] -> Double version of ex, or is a polymorphic version necessary?

(title inspired by this similar question)

Was it helpful?

Solution

I don't know the ad library, but since grad expects a function of type [AD s a] -> AD s a as its first parameter, you cannot expect to be able to pass it a function of type [Double] -> Double, since Double and AD are completely different types.

The generic function with Num constraint works, because AD itself is also an instance of Num, therefore in your working example, ex gets specialized to something like

ex :: (Mode s, Fractional a) => [AD s a] -> AD s a

If you want to specialize ex for calculations using Doubles, you need to give it a signature such as

ex :: Mode s => [AD s Double] -> AD s Double
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top