Haskell在do块中的where子句语法 [英] Haskell where clause syntax inside a do block
问题描述
我试图在Haskell的 do
块中重构 mapM _
函数调用。我想将lambda提取到(本地)命名的函数中,以使代码更具可读性。
我的代码最初看起来像这样:
do
- ...
mapM_(\ x - > x + 1)aList
return aValue
我想将它改为
do
- ...
mapM_ func aList
其中func x = x + 1
返回aValue
但是我在 return aValue code>行。我的实际lambda比较复杂:-),但我确实用这个lambda来尝试,以确保它不是lambda代码中的问题。
我怎么能重写这段代码?我应该在中使用让 ...
吗?
有三种类似的(但不同的)定义方式: 你可以附加 在
其中
子句在某些定义之后 - 主要是方程式的绑定。所以你可以在你的函数的末尾放置一个,或者用 let
或者一个周围的 where
子句定义。另一方面, let x = ... in ...
是一个 之后的部分,它是
let
之后的唯一地方是
内部做块,因为已经有一个隐式的作用域嵌套在他们第一次定义之后),你可以单独使用
let x = ...
。这与前面的表单非常相似 - let
之后的 do 块的其余部分实际上是
in ...
部分。
本地定义使用 do
块中定义的内容,唯一的选择是第三个(或将其他值作为参数传递)。然而,对于像你的例子那样的独立帮助函数,任何样式都可以。以下是您的示例,以演示每个元素:
第一种样式,其中 func
在 foo
,包括在其中
子句中定义的其他内容:
foo = do ...
mapM_ func aList
...
返回aValue
其中func x = x + 1
第二种样式,其中 func
仅在 let
表达式,在本例中为整个 do
块:
<$在
...
mapM_ func aList
...
中pre>
foo = let func x = x + 1
返回aValue
第三种方式,在中定义它do
块。在这种情况下, func
仅在 let
之后可见;在第一个 ...
中尚未定义。
foo = do ...
let func x = x + 1
mapM_ func aList
...
return aValue
哦,并且很好的衡量:既然 let ... in ...
是一个表达式,您还可以在任何有表达式的地方使用它,以命名一些本地定义。所以这里有另外一个例子:
pre $ $ $ $ $ $ $ $
...
return aValue
与前面一样, func
仅在 let
表达式中可见,在这种情况下,它是其后的单个表达式,无处可见。
I am trying to refactor a mapM_
function call inside a do
block in Haskell. I would like to extract the lambda to a (locally) named function to make the code more readable.
My code originally looks like this:
do
-- ...
mapM_ (\x -> x + 1) aList
return aValue
I would like to change it to
do
-- ...
mapM_ func aList
where func x = x + 1
return aValue
but I am getting a syntax error on the return aValue
line. My actual lambda is more complicated :-), but I did try it with this same lambda to make sure it was not an issue in the lambda code.
How can I rewrite this code? Should I use let
... in
instead?
There are three similar (but distinct) ways of defining stuff here:
You can attach
where
clauses after certain definitions--mostly equation-style bindings. So you could put one at the end of your function, or after something defined withlet
or a surroundingwhere
clause.On the other hand,
let x = ... in ...
is an expression that evaluates to the part afterin
, which is the only place the stuff afterlet
is visible.Inside a
do
block, because there's already an implicit nesting of scope (things are visible after they're first defined), you can use justlet x = ...
alone. This is really the same thing as the previous form--the rest of thedo
block after thelet
is effectively thein ...
portion.
If you want a local definition that uses something defined within the do
block, your only choice is the third (or passing the other value(s) as argument(s)). For an independent helper functions like your example, however, any style works. Here's your example, to demonstrate each:
The first style, where func
is visible anywhere in foo
, including anything else defined in the where
clause:
foo = do ...
mapM_ func aList
...
return aValue
where func x = x + 1
The second style, where func
is only visible inside the let
expression, which in this case is the entire do
block:
foo = let func x = x + 1
in do
...
mapM_ func aList
...
return aValue
And the third style, defining it inside the do
block. In this case, func
is only visible after the let
; in the first ...
it hasn't been defined yet.
foo = do ...
let func x = x + 1
mapM_ func aList
...
return aValue
Oh, and for good measure: Since let ... in ...
is an expression, you can also use it anywhere you have an expression, to name some local definitions. So here's another example:
foo = do ...
let func x = x + 1 in mapM_ func aList
...
return aValue
As before, func
is only visible inside the let
expression, which in this case is the single expression after it, nowhere else.
这篇关于Haskell在do块中的where子句语法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!