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

时间:2012-01-24 10:11:37

标签: haskell where-clause lambda

我正在尝试使用梯形规则在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

在上面,我使用

n - for the number of subintervals
d - for the width of each subinterval

除了lambda中绑定的参数a,b之外,这几乎可以正常工作。我明白了 错误讯息:

Not in scope: `b'
Not in scope: `a'

我可以理解a,b的范围仅限于lambda表达式,但是 在Haskell中是否有一个解决方法,以便我不必在上面的每个d中写入(b-a)/ n?

5 个答案:

答案 0 :(得分:19)

你认为你需要返回一个需要两个Float并返回一个Float的函数,但实际上这与你{{{}中另外两个Float参数没什么区别1}}函数和使用currying(即只是不提供它们,返回类型将是integrate)。

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

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 代替let ... in

where

答案 1 :(得分:4)

不确定

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

答案 2 :(得分:4)

你有很多解决方法。

如果你不知道除lambda表达式之外的任何绑定语法,你可以做到这一点(我最喜欢它因为它的理论美,但由于它的句法丑陋而从未使用过):

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

如果你喜欢定义并且只知道where - 语法,你可以这样做:

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

如果你也知道let - 语法,你可以这样做:

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

最后,如果您记得a -> (b -> c -> d)a -> b -> c -> d相同,那么您可以做到显而易见:

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

答案 3 :(得分:2)

如果你坚持在哪里:

integrate f = \a b -> case () of
    () ->  d * sum [ f (a + d*k) | k <- [0..n] ] - d/2.0 * (f a + f b)
           where 
               d = (b - a) / n
               n = 1000

看起来很漂亮,不是吗? 为了让案件看起来更有动力:

integrate f = \a b -> case (f a + f b) of
    fs ->  d * sum [ f (a + d*k) | k <- [0..n] ] - d/2.0 * fs
           where 
               d = (b - a) / n
               n = 1000

答案 4 :(得分: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