这里有三种相似(但不同)的定义方式:
您可以在某些定义之后附加where
子句——主要是方程式样式的绑定。因此,您可以将一个放在函数的末尾,或者在使用let
或周围where
子句定义的内容之后。
另一方面,let x = ... in ...
是一个表达式,其计算结果为 after 部分in
,这是后面的东西唯一let
可见的地方。
在一个do
块内,因为已经有一个隐式嵌套的范围(事物在它们第一次定义后可见),你可以let x = ...
单独使用。这实际上与之前的形式相同——do
之后的块的其余部分let
实际上是in ...
部分。
如果您想要一个使用do
块中定义的内容的本地定义,您唯一的选择是第三个(或将其他值作为参数传递)。但是,对于像您的示例这样的独立辅助函数,任何样式都可以使用。这是您的示例,以演示每个示例:
第一种样式, where 在func
中的任何地方可见,包括子句foo
中定义的任何其他内容:where
foo = do ...
mapM_ func aList
...
return aValue
where func x = x + 1
第二种样式, wherefunc
仅在let
表达式内部可见,在本例中是整个do
块:
foo = let func x = x + 1
in do
...
mapM_ func aList
...
return aValue
第三种样式,在do
块内定义。在这种情况下,func
仅在let
;之后可见 首先...
它还没有被定义。
foo = do ...
let func x = x + 1
mapM_ func aList
...
return aValue
哦,还有一个好处:既然let ... in ...
是一个表达式,你也可以在任何你有表达式的地方使用它,来命名一些本地定义。所以这是另一个例子:
foo = do ...
let func x = x + 1 in mapM_ func aList
...
return aValue
和以前一样,func
仅在let
表达式内部可见,在这种情况下,它是它之后的单个表达式,在其他任何地方都看不到。