Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Syntax Haskell:我可以在带有绑定运算符(>;=)的块之后使用where子句吗?_Syntax_Haskell_Monads - Fatal编程技术网

Syntax Haskell:我可以在带有绑定运算符(>;=)的块之后使用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

我有一个非常简单的问题。我想在使用绑定运算符的代码块之后使用where子句,但我得到了一个编译错误

下面是一个简单的例子:

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
decls
in

如果
g1
那么
e1
else

如果
g2
那么
e2
else


如果
gm
em
否则错误“模式不匹配”

或者,通过移除防护装置来简化事情

p
=
e
其中{
decls
}

糖是用来做什么的

p
=let
decls
in
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