haskell - 无法正确理解 Haskell 中的 lambda

标签 haskell lambda calculus

我有以下代码,基于此公式实现反函数计算:

enter image description here

enter image description here

derivation :: (Fractional a) => (a -> a) -> (a -> a)
derivation f = \ x -> ( ( f (x + dx) - f (x) ) / dx ) where dx = 0.1

evalA k f
  | k == 0 =  \x -> x
  | otherwise = \x -> (derivation (evalA (k-1) f) x) / (derivation f x)

inverseFun f x =
 let
   x0 = 3.0
   eps = 0.001
   iter k prev sum =
    let       
      elemA = evalA k f x0
      elemB = prev * (x - (f x0)) / (if k == 0 then 1 else k)
      newItem = elemA * elemB
    in
      if abs (newItem) < eps
      then sum
      else iter (k + 1) elemB (sum + newItem)
  in
    iter 0 1.0 0.0


f1 = \x -> 1.0 * x * x

main = do
  print $ inverseFun f1 2.5

我需要通过将 evalA 移动到 inverseFun 内来优化它,并存储上一步计算 A'n/F' 以在下一次迭代中重用它,如果可能的话。。据我了解,每次 evalA 返回某种函数,然后 x 应用,就在声明 elemA 之前。

如何转换我的 evalA 或重写它以存储以前的结果(显然,通过将这些结果传递到 iter 中)?

如果计算不太精确,请不要介意,它需要良好的 x0eps 选择。我的主要问题是 lambda 转换。

最佳答案

如果您更改 inverseFun 的定义,使得 (if k == 0 then 1 else k) 改为 fromIntegral (if k == 0然后 1::Int else k),然后您可以为所有函数提供类型签名:

derivation :: (Fractional a)        => (a -> a) -> a -> a
evalA      :: (Fractional a)        => Int -> (a -> a) -> a -> a
inverseFun :: (Fractional a, Ord a) => (a -> a) -> a -> a
f1         :: (Fractional a)        => a -> a

这肯定有帮助。

这对于我解决您的问题实际上很重要,因为我们需要 kInt,而您已将其用作 Fractional a => 一个fromIntegral 修复了这个问题,但它需要知道它是一个 Int,所以我只是添加了内联类型签名来帮助编译器。

由于您的函数仅依赖于先前的单个值,因此您可以使用 Prelude 中我们方便的 friend ,iterate::(a -> a) -> a -> [a] 。这会一遍又一遍地应用一个函数,产生无限的值列表。然后我们可以在任何点对其进行索引以获得所需的结果(这就是为什么拥有 k 一个 Int 很重要!)。

我们的函数看起来像

evalA :: Fractional a => Int -> (a -> a) -> a -> a
evalA k f = iterate go id !! k
    where
        go = ???

这里 id\x -> x 的基本情况相同,只是更短并且具有更多优化规则。它用作生成此列表的初始值。为了实现实际的计算 go,我们需要它接受之前的结果作为参数:

    where
        go prev = \x -> derivation prev x / derivation f x

但是 hlint 认为这是“糟糕的风格”,因此建议将其转换为以下形式

    where
        go prev x = derivation prev x / derivation f x

就是这样!我对其进行了测试,并得到了与您的示例输入完全相同的结果。完整代码可查看here .

关于haskell - 无法正确理解 Haskell 中的 lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26221606/

相关文章:

plot - 最小化 Mathematica 中自定义分布的 NExpectation

math - 在 Maple 中执行从负无穷大到无穷大的积分

haskell - 将 cabal 与多个 GHC 版本一起使用

java - 如何在 Java 中对某些元素进行排序并保留其他元素?

c# - 预加载多对多 - EF Core

java - 使用方法引用来检查 boolean 值匹配而不是 lambda

python - scipy.integrate.quad 大数精度

function - 链接多参数函数

haskell - 如何定义适合证明的类型级列表索引?

haskell - haskell 中的类型 ()::() 是什么意思?