Haskell中符号的好处

时间:2014-03-23 06:47:40

标签: function haskell scope where-clause

显式函数定义的优缺点是什么,而不是Haskell中的符号?

显式函数定义:

foo :: Integer -> Integer
foo a = bar a
  where
    bar :: Integer -> Integer
    bar a = Some code here

而不是:

foo :: Integer -> Integer
foo a = bar a

bar :: Integer -> Integer
bar a = Some code here

为什么我会使用一个而不是另一个?在效率方面有什么需要注意的吗?安全?代码可重用性?代码可读性?

2 个答案:

答案 0 :(得分:9)

如果您的辅助功能不会在其他任何地方使用,最好不要污染命名空间并使用本地定义。

当你的外部函数只有一个顶级“模式”时,where子句可以简化辅助函数的定义,因为外部函数的参数将在范围内。

outer x v z f = undefined
    where 
        inner i = i + x + v + z + f

outer x v z f = undefined

inner x v z f i = i + x + v + z + f

如果您的函数有多个顶级“模式”,则无法使用where在模式之间共享绑定。您必须定义顶级绑定。

使用where的某些方式可能会导致非明显的性能损失。这个定义(取自let vs where上的HaskellWiki文章)

fib x = map fib' [0 ..] !! x
    where
      fib' 0 = 0
      fib' 1 = 1
      fib' n = fib (n - 1) + fib (n - 2)

比这个慢:

fib = (map fib' [0 ..] !!)
    where
      fib' 0 = 0
      fib' 1 = 1
      fib' n = fib (n - 1) + fib (n - 2)

并且比在顶层定义fib'要慢。

原因是,在第一个定义中,为fib'的每次调用创建了一个新的fib。解释here

答案 1 :(得分:0)

如果你只需要在foo的范围内使用bar,那么在" where"中声明它更具可读性和更好的信息隐藏性。如果bar应该在foo之外可以重用,那么它需要被声明为与foo平行。