AD反思 - 它是如何工作的?

时间:2017-05-10 10:36:34

标签: haskell reflection typeclass instances automatic-differentiation

我已经看过class Floating包,我通过提供Prelude Debug.SimpleReflect Numeric.AD> diff atanh x recip (1 - x * x) * 1 的不同实例然后实现衍生规则来理解它是如何自动区分的。

但是在示例中

AST

我们发现它可以将函数表示为f :: Floating a => a -> a f x = x^2 ,并将它们显示为带有变量名称的字符串。

我想知道他们是怎么做到的,因为我写的时候:

f :: Something -> Something

无论我提供什么实例,我都会获得功能 f :: AST 而不是像f :: String或{{1}}

这样的表示

实例不能知道"参数是什么。

他们是如何做到的?

1 个答案:

答案 0 :(得分:3)

实际上,它与AD包无关,而且与x中的diff atanh x无关。

要看到这一点,让我们定义我们自己的AST类型

data AST = AST :+ AST
         | AST :* AST
         | AST :- AST
         | Negate AST
         | Abs AST
         | Signum AST
         | FromInteger Integer
         | Variable String

我们可以为此类型定义Num实例

instance Num (AST) where
  (+) = (:+)
  (*) = (:*)
  (-) = (:-)
  negate = Negate
  abs = Abs
  signum = Signum
  fromInteger = FromInteger

Show实例

instance Show (AST) where
  showsPrec p (a :+ b) = showParen (p > 6) (showsPrec 6 a . showString " + " . showsPrec 6 b)
  showsPrec p (a :* b) = showParen (p > 7) (showsPrec 7 a . showString " * " . showsPrec 7 b)
  showsPrec p (a :- b) = showParen (p > 6) (showsPrec 6 a . showString " - " . showsPrec 7 b)
  showsPrec p (Negate a) = showParen (p >= 10) (showString "negate " . showsPrec 10 a)
  showsPrec p (Abs a) = showParen (p >= 10) (showString "abs " . showsPrec 10 a)
  showsPrec p (Signum a) = showParen (p >= 10) (showString "signum " . showsPrec 10 a)
  showsPrec p (FromInteger n) = showsPrec p n
  showsPrec _ (Variable v) = showString v

现在,如果我们定义一个函数:

f :: Num a => a -> a
f a = a ^ 2

和AST变量:

x :: AST
x = Variable "x"

我们可以运行该函数来生成整数值或AST值:

λ f 5
25
λ f x
x * x

如果我们希望能够将您的AST类型与您的函数f :: Floating a => a -> a; f x = x^2一起使用,我们需要扩展其定义以允许我们实现Floating (AST)