显式函数定义的优缺点是什么,而不是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
为什么我会使用一个而不是另一个?在效率方面有什么需要注意的吗?安全?代码可重用性?代码可读性?
答案 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平行。