Haskell中符号的好处

Abr*_*m P 4 haskell scope function where-clause

与Haskell中的符号相反,显式函数定义的优缺点是什么?

显式函数定义:

foo :: Integer -> Integer
foo a = bar a
  where
    bar :: Integer -> Integer
    bar a = Some code here
Run Code Online (Sandbox Code Playgroud)

而不是:

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

bar :: Integer -> Integer
bar a = Some code here
Run Code Online (Sandbox Code Playgroud)

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

dan*_*iaz 9

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

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

outer x v z f = undefined
    where 
        inner i = i + x + v + z + f
Run Code Online (Sandbox Code Playgroud)

outer x v z f = undefined

inner x v z f i = i + x + v + z + f
Run Code Online (Sandbox Code Playgroud)

如果您的函数有多个顶级"模式",那么您无法使用模式共享绑定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)
Run Code Online (Sandbox Code Playgroud)

比这个慢:

fib = (map fib' [0 ..] !!)
    where
      fib' 0 = 0
      fib' 1 = 1
      fib' n = fib (n - 1) + fib (n - 2)
Run Code Online (Sandbox Code Playgroud)

并且比fib'在顶层定义慢.

原因是,在第一个定义中,fib'为每次调用创建一个new fib.这里解释一下.