为什么"where"在列表理解中产生解析错误,而"let"没有?



让我们定义一个名为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,因此在列表推导中是不正确的。

相关内容

最新更新