Haskell中的where关键字有哪些好处?

4

在Haskell中,明确函数定义和where符号有哪些优缺点?

明确函数定义:

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个回答

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的方式可能会导致不明显的性能损失。这个定义(摘自HaskellWiki关于let vs where的文章)
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'。这里有解释(英文链接)


0

如果你只需要在foo的范围内使用bar,那么在“where”中声明它会更易读且信息隐藏得更好。如果bar应该在foo之外可重用,则需要将其与foo并列声明。


这并不完全是一个答案。 - Nikita Volkov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接