所以我有一个双数课程:
data Dual a = !a :+ !a
instance [safe] Eq a => Eq (Dual a)
instance [safe] RealFloat a => Floating (Dual a)
instance [safe] RealFloat a => Fractional (Dual a)
instance [safe] RealFloat a => Num (Dual a)
instance [safe] Read a => Read (Dual a)
instance [safe] Show a => Show (Dual a)
现在我想编写一个函数,它接受一个数值函数并将其导数作为数值函数。(使用自动微分)。
这是我想出的:
{-# LANGUAGE FlexibleContexts #-}
autoDiff :: Floating a => (Dual a -> Dual a) -> a -> a
autoDiff f = dualPart . f . (flip (:+) 1)
现在举个例子sin
,这是我得到的:
*AutoDiff> :t sin
sin :: Floating a => a -> a
*AutoDiff> :t autoDiff sin
autoDiff sin :: RealFloat a => a -> a
*AutoDiff> :t autoDiff (autoDiff sin)
autoDiff (autoDiff sin) :: (RealFloat (Dual a), RealFloat a) => a -> a
*AutoDiff> sin 1
0.8414709848078965
*AutoDiff> (autoDiff sin) 1
0.5403023058681398
*AutoDiff> (autoDiff (autoDiff sin)) 1
<interactive>:109:1: error:
• No instance for (RealFloat (Dual a0)) arising from a use of ‘it’
• In a stmt of an interactive GHCi command: print it
我不知道错误消息告诉我什么。我试过玩弄,forall
但我不能采用通用函数,通过它坚持对偶并返回一个通用函数。
那么我如何迭代autoDiff
以获得更高的导数,甚至在 Haskell 的类型系统中是否有可能呢?