Haskell在do块中的where子句语法 [英] Haskell where clause syntax inside a do block

查看:696
本文介绍了Haskell在do块中的where子句语法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在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 with let or a surrounding where clause.

  • On the other hand, let x = ... in ... is an expression that evaluates to the part after in, which is the only place the stuff after let 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 just let x = ... alone. This is really the same thing as the previous form--the rest of the do block after the let is effectively the in ... 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆