Syntax Haskell:我可以在带有绑定运算符(>;=)的块之后使用where子句吗?
我有一个非常简单的问题。我想在使用绑定运算符的代码块之后使用where子句,但我得到了一个编译错误 下面是一个简单的例子:Syntax Haskell:我可以在带有绑定运算符(>;=)的块之后使用where子句吗?,syntax,haskell,monads,Syntax,Haskell,Monads,我有一个非常简单的问题。我想在使用绑定运算符的代码块之后使用where子句,但我得到了一个编译错误 下面是一个简单的例子: main = putStrLn "where clause test:" >> return [1..10] >>= \list -> print list' where list' = reverse list -- test1.hs:5:28: Not in scope: `list' 我可以使用l
main =
putStrLn "where clause test:" >>
return [1..10] >>= \list ->
print list'
where list' = reverse list -- test1.hs:5:28: Not in scope: `list'
我可以使用let子句作为列表中的
main =
putStrLn "where clause test:" >>
return [1..10] >>= \list ->
let list' = reverse list -- works of course
in print list'
但是如果我能用where子句,我真的很想
我还尝试了do符号
main = do
putStrLn "where clause test:"
list <- return [1..10]
print list'
where list' = reverse list --test3.hs:5:30: Not in scope: `list'
main=do
putStrLn“where子句测试:”
list据我所知,where子句只在本地绑定中使用。>>(=)绑定语句的内部不是本地绑定(该语句中有两种不同的绑定)
与此相比:
main = f [1..10]
f list =
putStrLn "where clause test:" >> print list'
where list' = reverse list
您可能希望参考-不确定这会有多大帮助
如果我错了,肯定会有人纠正我,但我很确定你不能用上面展示的样式使用where子句<代码>列表
永远不会在where子句的范围内,除非它是函数的参数。问题是让
-在
中是一个表达式,可以在其他表达式中使用,而其中
只能在(模块|类|实例| GADT |…)声明或(函数|模式)绑定上使用
根据Haskell 98年的报告
p|g1=
e1|g2
=
e2…
|gm
=
em其中{
decls}
糖是用来做什么的
p=let
declsin
如果
g1那么
e1else
如果
g2那么
e2else
…
如果
gm则
em否则错误“模式不匹配”
或者,通过移除防护装置来简化事情
p=
e其中{
decls}
糖是用来做什么的
p=let
declsin
e
在函数和模式绑定中。即使您的e是一个do{
..}
构造,这也是正确的
如果你想在一个更大的表达式中有一个特定子表达式的局部绑定,你需要在中使用let
-(或者干脆在do
中使用let
,但这只是let
-in
的糖分)
你甚至不会写字
main = do
putStrLn "where clause test: "
list <- return [1..10]
(print list' where list' = reverse list)
这是合法的(如果有点做作)。正如ephemient解释的那样,你不能像你那样使用where
子句
发生此错误的原因是,在此代码中:
main =
return [1..10] >>= \list ->
print list'
where
list' = reverse list
where
-子句附加到主函数
这是一个带更多括号的函数:
main = return [1..10] >>= (\list -> print list')
where
list' = reverse list
我认为很明显为什么会出现“超出范围
”错误:列表
的绑定在主
表达式的深处,而不是where
子句可以达到的
在这种情况下我通常会做什么(我已经被同样的事情咬了很多次)。我只需引入一个函数并将列表作为参数传递
main = do
list <- return [1..10]
let list' = f list
print list'
where
f list = reverse list -- Consider renaming list,
-- or writing in point-free style
main=do
列出一个lambda抽象是一个表达式,而不是一个声明或绑定,尽管它可以绑定新名称…哇,这是谁写的?我认为这是正确的,如果没有尽可能完整的话。这是不相关的。OP想要使用“列表”,这是一系列一元计算的中间结果;不是一个来自单子之外的值为什么不仅仅是“let list”=reverse list“?在最后一个例子中?谢谢,当我对这种语言有一些基本问题时,我应该更经常地参考Haskell报告。@newacct:OP的问题已经包括了这个变体,它显然是有效的。谢谢,你的例子加了更多的括号,让我明白了这一点。
main = do
list <- return [1..10]
let list' = f list
print list'
where
f list = reverse list -- Consider renaming list,
-- or writing in point-free style