查看产品的差异化规则:
(u v)' = u' v + v' u
你需要知道什么才能使产品与众不同?你需要知道子项的导数(
u'
,
v'
)以及它们的值(
u
,
v
)
这正是
顺形性
给你。
para
:: Functor f
=> (f (b, Term f) -> b)
-> Term f -> b
para g (In a) = g $ (para g &&& id) <$> a
derivePara :: Term Expr -> Term Expr
derivePara = para $ In . \case
Var -> Const 1
Const _ -> Const 0
Plus x y -> Plus (fst x) (fst y)
Mul x y -> Plus
(In $ Mul (fst x) (snd y))
(In $ Mul (snd x) (fst y))
Pow x c -> Mul
(In (Const c))
(In (Mul
(In (Pow (snd x) (c-1)))
(fst x)))
在顺形性中,
fst
允许您访问子项的派生项,而
snd
给你这个词本身。
作为这个问题的扩展,是否有一个用于区分和消除“空”表达式的递归方案,例如
Plus (Const 0)
由于微分而产生的x——在一次数据传递中?
是的,它仍然是顺形的。最简单的方法是使用智能构造函数,例如
plus :: Term Expr -> Term Expr -> Expr (Term Expr)
plus (In (Const 0)) (In x) = x
plus (In x) (In (Const 0)) = x
plus x y = Plus x y
在定义代数时使用它们。你也可以把它表示为某种准卡塔融合。