jto*_*bin 5 haskell types automatic-differentiation constraint-kinds
我几乎没有成功地绕着包装中涉及的类型的基本管道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]
Run Code Online (Sandbox Code Playgroud)
哪里grad有类型:
grad
:: (Num a, Traversable f) =>
(forall (s :: * -> *). Mode s => f (AD s a) -> AD s a)
-> f a -> f a
Run Code Online (Sandbox Code Playgroud)
如果我改变的类型签名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
Run Code Online (Sandbox Code Playgroud)
当用实例化的Double类替换看似任何类型的构造函数时,会发生相同的行为. *Num
当Traversable f列表是一个列表时,第一个参数grad必须具有[AD s a] -> AD s a某些可接受的类型Mode- 例如,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,因为Double并且AD是完全不同的类型.
带有Num约束的泛型函数起作用,因为AD它本身也是一个实例Num,因此在你的工作示例中,它ex专门用于类似的东西
ex :: (Mode s, Fractional a) => [AD s a] -> AD s a
Run Code Online (Sandbox Code Playgroud)
如果你想专攻ex使用双打的计算,你需要给它一个签名,如
ex :: Mode s => [AD s Double] -> AD s Double
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
392 次 |
| 最近记录: |