围绕包装中涉及的类型的基本管道,我几乎没有成功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
,还是需要多态版本?
(标题受这个类似问题的启发)