Numeric.AD和打字问题

时间:2011-05-09 14:31:37

标签: haskell types automatic-differentiation

我正在尝试使用Numeric.AD和自定义Expr类型。我想算一算 用户输入表达的符号梯度。第一次试验有一个常数 表达很好:

calcGrad0 :: [Expr Double]
calcGrad0 = grad df vars
  where
   df [x,y] = eval (env [x,y]) (EVar "x"*EVar "y")
   env vs = zip varNames vs
   varNames = ["x","y"]
   vars = map EVar varNames

这有效:

>calcGrad0
[Const 0.0 :+ (Const 0.0 :+ (EVar "y" :* Const 1.0)),Const 0.0 :+ (Const 0.0 :+ (EVar "x" :* Const 1.0))]

但是,如果我将表达式作为参数拉出来:

calcGrad1 :: [Expr Double]
calcGrad1 = calcGrad1' (EVar "x"*EVar "y")
calcGrad1' e = grad df vars
  where
   df [x,y] = eval (env [x,y]) e
   env vs = zip varNames vs
   varNames = ["x","y"]
   vars = map EVar varNames

我得到了

Could not deduce (a ~ AD s (Expr a1))
from the context (Num a1, Floating a)
  bound by the inferred type of
           calcGrad1' :: (Num a1, Floating a) => Expr a -> [Expr a1]
  at Symbolics.hs:(60,1)-(65,29)
or from (Mode s)
  bound by a type expected by the context:
             Mode s => [AD s (Expr a1)] -> AD s (Expr a1)
  at Symbolics.hs:60:16-27
  `a' is a rigid type variable bound by
      the inferred type of
      calcGrad1' :: (Num a1, Floating a) => Expr a -> [Expr a1]
      at Symbolics.hs:60:1
Expected type: [AD s (Expr a1)] -> AD s (Expr a1)
  Actual type: [a] -> a
In the first argument of `grad', namely `df'
In the expression: grad df vars

我如何让ghc接受这个?

2 个答案:

答案 0 :(得分:5)

我猜您忘记应用liftExpr转换为AD s Expr

如果您有兴趣使用ad包进行符号区分。 Lennart Augustsson的traced套餐效果很好。

答案 1 :(得分:1)

当GHC无法推导出有效函数的类型相等签名时,就像在您的情况下一样,解决方案是为函数提供类型签名。我不知道这个库的接口。但是,我的猜测是正确的签名是calcGrad1 :: (Num a, Floating a) => Expr a -> [Expr a]