Haskell中函数的相等性

qua*_*dev 14 haskell equality

我试图定义一个函数,它将获取一个Double -> Double函数并返回其数学导数.我尝试过以下操作:

der :: (Double -> Double) -> (Double -> Double)
der f
    | f == exp = exp
    | otherwise = undefined
Run Code Online (Sandbox Code Playgroud)

但哈斯克尔不支持==Double -> Double值.我在Haskell尝试做什么是不可能的?

huo*_*uon 24

是的,你所要做的是在Haskell不可能的,而且一般:确定两个函数是否对所有可能的输入相等(不只是检查每个输入值,如果这甚至有可能)等价于解决停机问题.

但是,在您的特定情况下,您可以使用模拟a的自定义类型Double(即具有相同的实例,因此可以代替它)来绕过它,而不是评估数字,它构造一个抽象表示这些功能的作用.Expr代表数学函数定义的右侧f(x) = ....

data Expr = X | Const Double |
            Add Expr Expr | Mult Expr Expr |
            Negate Expr | Inverse Expr |
            Exp Expr | Log Expr | Sin Expr | ...
       deriving (Show, Eq)

instance Num Expr where
    (+) = Add
    (*) = Mult
    ...
instance Fractional Expr where
    recip = Inverse
    ...
instance Floating Expr where
    pi = Const pi
    exp = Exp
    log = Log
    sin = Sin
    ...
Run Code Online (Sandbox Code Playgroud)

然后,您可以定义在函数和Floatings 之间进行转换的转换函数:

{-# LANGUAGE Rank2Types #-}

fromFunction :: (forall a. Floating a => (a -> a)) -> Expr
fromFunction f = f X

toFunction :: Expr -> (Double -> Double)
toFunction X = \x -> x
toFunction (Const a) = const a
toFunction (Add a b) = \x -> (toFunction a x) + (toFunction b x)
...
Run Code Online (Sandbox Code Playgroud)

您还可以定义一个Expr区分表达式的函数:

diff X = Const 1
diff (Const _) = Const 0
diff (Add a b) = Add (diff a) (diff b)
diff (Exp a) = Mult (diff a) (Exp a)
...
Run Code Online (Sandbox Code Playgroud)

拥有所有这些部分应该意味着您可以区分(某些)功能,例如

f x = sin x + cos x * exp x
f' = toFunction . diff . fromFunction $ f
Run Code Online (Sandbox Code Playgroud)

注意事项:

  • 这不会起作用,
  • 定义一个完整的diff :: Expr -> Expr实例Eq是棘手的(它相当于Halting问题,因为它基本上是在询问两个函数是否相等),
  • 我实际上没有测试过这些代码,
  • 差异化和重建是在运行时完成的,因此产生的函数很可能非常慢.

  • 为了达到这个目的,你需要的不仅仅是一个`X`组件.事实上,`Eq`实例很棘手.我曾经尝试过,但我的平等检查未能在可监督的时间内完成,表达式比例如"∂/∂x(a + x)/ sin x"更复杂. (2认同)

aug*_*tss 11

通常不可能测试函数是否相等,因为函数相等应该是扩展的,即如果它们为所有参数给出相同的结果,则两个函数是相等的.

但是还有其他方法可以在Haskell中定义使用不同类型的衍生物.例如,自动微分,更简单的AD版本.

  • 这不是数字差异,它与此非常不同.它既不是数字的,也不是象征性的,而是第三种神秘的选择.:) (5认同)