围绕包装中涉及的类型的基本管道,我几乎没有成功ad。例如,以下工作完美:
import Numeric.AD
ex :: Num a => [a] -> a
ex [x, y] = x + 2*y
> grad ex [1.0, 1.0]
[1.0, 2.0]
哪里grad有类型:
grad
:: (Num a, Traversable f) =>
(forall (s :: * -> *). Mode s => f (AD s a) -> AD s a)
-> f a -> f a
ex如果我更改to的类型签名[Double] -> Double并尝试相同的事情,我会得到
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
当用实例化Double的 kind 替换看似任何类型的构造函数时,也会发生相同的行为。 *Num
当Traversable f是列表时, 的第一个参数grad必须具有[AD s a] -> AD s a某些可接受的类型Mode- 例如,Reverse. 但显然用户grad不必处理AD构造函数或Mode直接处理。窥视这些内部结构让我有点困惑。具体来说,我无法按照种类/类型追踪来区分 usingNum a => [a] -> a和[Double] -> Double.
为什么类型签名[Double] -> Double会导致问题grad?就普通的旧库使用而言:有什么方法可以使用 的[Double] -> Double版本ex,还是需要多态版本?
(标题受这个类似问题的启发)