为什么`where`在列表理解中产生一个解析错误,但是`let`不会?

时间:2015-04-11 10:16:17

标签: haskell list-comprehension where-clause

让我们定义一个名为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

2 个答案:

答案 0 :(得分:7)

正如您在Haskell报告(https://www.haskell.org/onlinereport/exps.html#list-comprehensions)中所看到的,列表理解在左侧表达。 let是一个表达式,而where是顶级声明的一部分。因此,它不允许在那里。

答案 1 :(得分:2)

这是因为列表推导等同于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仅在描述变量后才被允许,因此在列表推导中不正确。