Numeric.AD 函数中可接受的类型



我对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的类型签名更改为[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

当用实例化Num的 kind * 替换Double看似任何类型的构造函数时,也会发生相同的行为。

Traversable f是一个列表时,grad的第一个参数必须具有某些可接受的Mode的类型[AD s a] -> AD s a - 例如,Reverse 。 但显然,grad的用户不必直接与AD构造函数或Mode打交道。 窥视这些内部因素让我有点困惑;具体来说,我无法遵循种类/类型线索来区分使用 Num a => [a] -> a[Double] -> Double .

为什么类型签名[Double] -> Double导致grad问题? 就普通的旧库使用而言:有没有办法使用 [Double] -> Double 版本的ex,还是需要多态版本?

(标题灵感来自这个类似的问题(

我不知道ad库,但由于grad期望将 [AD s a] -> AD s a 类型的函数作为其第一个参数,因此您不能期望能够向它传递 [Double] -> Double 类型的函数,因为DoubleAD是完全不同的类型。

具有Num约束的泛型函数有效,因为AD本身也是Num的实例,因此在您的工作示例中,ex专门用于类似

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

如果要专门ex使用双精度进行计算,则需要为其提供签名,例如

ex :: Mode s => [AD s Double] -> AD s Double

相关内容

  • 没有找到相关文章

最新更新