为什么 `where` 在列表理解中产生解析错误,而 `let` 却没有?
Why `where` produces a parse error inside list comprehension, but `let` doesn't?
让我们定义一个名为 func
的简单函数:
func :: [Int] -> [Int]
我想在定义这个伪函数时在列表理解中使用 where
子句。
func xs = [ y where y = x + 1 | x <- xs]
不幸的是,在尝试编译时我收到以下消息:
parse error on input `where'
如果我决定使用 let
子句,一切正常:
func xs = [ let y = x + 1 in x | x <- xs] -- compilation successful
为什么我不能像我最初打算的那样使用 where
?
正如您在 Haskell 报告 (https://www.haskell.org/onlinereport/exps.html#list-comprehensions) 中看到的那样,列表解析在左侧采用表达式。 let
是一个表达式,而 where
是顶级声明的一部分。因此,那里是不允许的。
这是因为列表理解等同于 do
-语法。
为了清楚起见,这:
[f a b q | a <- as, b <- bs, let q = a + b]
相当于:
do a <- as
b <- bs
let q = a + b
return (f a b q)
和 let
表达式允许出现在 do
块中。
至于为什么 where
子句不被允许,它们的目的是在顶级声明中提供一个临时范围。
即:
binding = la da fu gu
where la a b c = c a b
da = 6
...
换句话说,where
只有在变量被描述后才被允许,因此在列表推导中是不正确的。
让我们定义一个名为 func
的简单函数:
func :: [Int] -> [Int]
我想在定义这个伪函数时在列表理解中使用 where
子句。
func xs = [ y where y = x + 1 | x <- xs]
不幸的是,在尝试编译时我收到以下消息:
parse error on input `where'
如果我决定使用 let
子句,一切正常:
func xs = [ let y = x + 1 in x | x <- xs] -- compilation successful
为什么我不能像我最初打算的那样使用 where
?
正如您在 Haskell 报告 (https://www.haskell.org/onlinereport/exps.html#list-comprehensions) 中看到的那样,列表解析在左侧采用表达式。 let
是一个表达式,而 where
是顶级声明的一部分。因此,那里是不允许的。
这是因为列表理解等同于 do
-语法。
为了清楚起见,这:
[f a b q | a <- as, b <- bs, let q = a + b]
相当于:
do a <- as
b <- bs
let q = a + b
return (f a b q)
和 let
表达式允许出现在 do
块中。
至于为什么 where
子句不被允许,它们的目的是在顶级声明中提供一个临时范围。
即:
binding = la da fu gu
where la a b c = c a b
da = 6
...
换句话说,where
只有在变量被描述后才被允许,因此在列表推导中是不正确的。