为什么 x*x where x = 6 在 Haskell 中失败?

Rah*_*hat -1 haskell where-clause ghci haskell-platform

我一直在阅读 Haskell 的功能性思考以学习 Haskell,我遇到了这一点。在书中它说 where 子句不限定表达式,而是限定整个右侧的定义。我不太明白这个意思。

K. *_*uhr 6

这本书意味着以下“表达式”不是有效的 Haskell 语法:

x*x where x = 6
Run Code Online (Sandbox Code Playgroud)

您可以通过在 GHCi 提示符下输入它来查看它是无效的:

> x*x where x=6
<interactive>:11:5: error: parse error on input ‘where’
Run Code Online (Sandbox Code Playgroud)

或者在需要表达式的程序中使用它:

mybrokenprogram = (x * x where x = 6)   -- gives a parse error
Run Code Online (Sandbox Code Playgroud)

对比一下:

let x=6 in x*x
Run Code Online (Sandbox Code Playgroud)

它在 GHCi 提示符下工作:

> let x=6 in x*x
36
Run Code Online (Sandbox Code Playgroud)

并作为另一个示例的一部分工作正常:

myawesomeprogram = (let x = 6 in x*x)
Run Code Online (Sandbox Code Playgroud)

这本书解释了一个where子句适用于其相关定义的整个右侧:

myfinewhereclause = x*x+x
    where x = 6*6
Run Code Online (Sandbox Code Playgroud)

此处,该where子句提供了x适用于整个右侧的定义x*x+x。即使x在范围内有一些替代定义,该where条款也会x为整个 RHS重新定义:

my_argument_x_is_ignored x = x*x+x where x = 6*6
Run Code Online (Sandbox Code Playgroud)

此处,该where子句提供了x适用x于表达式 中的每种用法的定义x*x+x。它不仅适用于 的最后一次使用x,而且您不能使用括号使其仅适用于 的最后一次使用x

wontwork x = x*x + (x where x=6*6)   -- won't work: bad syntax
Run Code Online (Sandbox Code Playgroud)

没什么深奥的。这只是where语法的工作方式。