Haskell:where子句引用lambda中的绑定变量

Byl*_*tor 13 lambda haskell where-clause

我试图使用梯形规则在Haskell中数字地集成一个函数,返回一个反导数,它带有参数a,b,用于集成区间的端点.

integrate :: (Float -> Float) -> (Float -> Float -> Float)

integrate f
  = \ a b -> d * sum [ f (a + d*k) | k <- [0..n] ] - d/2.0 * (f a + f b)
    where
      d = (b - a) / n
      n = 1000
Run Code Online (Sandbox Code Playgroud)

在上面,我用

n - for the number of subintervals
d - for the width of each subinterval
Run Code Online (Sandbox Code Playgroud)

除了lambda中绑定的参数a,b之外,这几乎可以正常工作.我收到错误消息:

Not in scope: `b'
Not in scope: `a'
Run Code Online (Sandbox Code Playgroud)

我可以理解a,b的范围仅限于lambda表达式,但是在Haskell中有一个解决方法,所以我不必在上面的每次出现时写(ba)/ n吗?

Mat*_*ton 19

你认为你需要返回一个需要两个Floats并返回a 的函数Float,但实际上Float你在integrate函数中使用两个额外的参数并使用currying 没有什么不同(即只是不提供它们而返回类型将是Float -> Float -> Float).

所以你可以像这样重写你的功能

integrate :: (Float -> Float) -> Float -> Float -> Float

integrate f a b
  = d * sum [ f (a + d*k) | k <- [0..n] ] - d/2.0 * (f a + f b)
    where
      d = (b - a) / n
      n = 1000
Run Code Online (Sandbox Code Playgroud)

或者您可以使用let ... in而不是where:

integrate f
  = \a b ->
      let d = (b - a / n)
          n = 1000
      in d * sum [ f (a + d * k) | k <- [0..n] ] - d/2.0 * (f a + f b)
Run Code Online (Sandbox Code Playgroud)

  • FWIW,Matthew省略了类型签名中的括号,但这不是必需的.您可以保持类型签名相同,并以这种新方式编写函数体.这两个签名*完全相同*. (2认同)

viv*_*ian 1

尝试:

integrate f a b = d * sum [ f (a + d*k) | k <- [0..n] ] - d/2.0 * (f a + f b)
    where
      d = (b - a) / n
      n = 1000
Run Code Online (Sandbox Code Playgroud)