Ral*_*lph 24 syntax haskell where-clause
我试图在Haskell中mapM_的do块内重构一个函数调用.我想将lambda提取到(本地)命名函数,以使代码更具可读性.
我的代码最初看起来像这样:
do
-- ...
mapM_ (\x -> x + 1) aList
return aValue
Run Code Online (Sandbox Code Playgroud)
我想改成它
do
-- ...
mapM_ func aList
where func x = x + 1
return aValue
Run Code Online (Sandbox Code Playgroud)
但我在线上遇到语法错误return aValue.我的实际lambda更复杂:-),但我确实用同样的lambda尝试它,以确保它不是lambda代码中的问题.
我该如何重写这段代码?我应该用let...... in代替吗?
C. *_*ann 33
这里有三种类似(但不同)的方法来定义东西:
您可以where在某些定义之后附加子句 - 主要是方程式绑定.因此,你可以在函数的末尾添加一个函数,或者在使用let或使用around where子句定义之后.
另一方面,let x = ... in ...是一个表达式,评估后面的部分in,这是后面的东西唯一let可见的地方.
在一个do块内部,因为已经有一个隐式的范围嵌套(事物在首次定义后可见),你可以let x = ...单独使用.这与之前的形式完全相同 - 其余的do块之后let就是有效的in ...部分.
如果你想要一个使用do块内定义的东西的本地定义,你唯一的选择是第三个(或者将其他值作为参数传递).但是,对于像您的示例一样的独立辅助函数,任何样式都可以.以下是您的示例,以演示每个:
第一种样式,在func任何地方都可见foo,包括where子句中定义的任何其他内容:
foo = do ...
mapM_ func aList
...
return aValue
where func x = x + 1
Run Code Online (Sandbox Code Playgroud)
第二种样式,func只在let表达式中可见,在这种情况下是整个do块:
foo = let func x = x + 1
in do
...
mapM_ func aList
...
return aValue
Run Code Online (Sandbox Code Playgroud)
第三种风格,在do块内定义它.在这种情况下,func只有在可见之后let; 在第一个...它尚未定义.
foo = do ...
let func x = x + 1
mapM_ func aList
...
return aValue
Run Code Online (Sandbox Code Playgroud)
哦,并且好的措施:既然let ... in ...是表达式,你也可以在任何有表达式的地方使用它,来命名一些本地定义.所以这是另一个例子:
foo = do ...
let func x = x + 1 in mapM_ func aList
...
return aValue
Run Code Online (Sandbox Code Playgroud)
和以前一样,func只在let表达式中可见,在这种情况下,表达式之后是单个表达式,在其他地方.
ham*_*mar 10
另一种选择是使用forM_而不是mapM_翻转参数的顺序.然后,您可以将$运算符与尾随的lambda表达式一起使用,如下所示:
do
forM_ aList $ \x -> do
...
return aValue
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8501 次 |
| 最近记录: |