Haskell:"where"子句有多个顶级绑定?

Ric*_*man 2 haskell

这必须是一个常见问题解答,但我无法在暴风雪中找到关于letvs 的问题where,所以...我想用多个顶级绑定来表示一个表达式,而将它仅限于那些绑定.如果我有一个带有"where"子句的单个绑定,我可以这样做:

foo = ... bar ... bar ...
    where bar = ...
Run Code Online (Sandbox Code Playgroud)

如果我有相同顶级绑定的多个保护方程式:

foo = x | ... bar ...
        | ... bar ...
    where bar = ...
Run Code Online (Sandbox Code Playgroud)

但似乎没有办法在"where"的范围内有多个顶级绑定,这是这样的:

foo = ... bar ...
baz = ... bar ...
    where bar = ...
Run Code Online (Sandbox Code Playgroud)

我也必须bar在顶层定义.这不是什么大问题,但更贴近它的范围会更好.我错过了什么吗?谢谢!

bhe*_*ilr 5

你不会错过任何东西,只是a where只适用于单个表达式.因此,在第一个示例中,您只有一个表达式,在第二个示例中,单个表达式是您的守护,在第三个示例中,您有两个不同的表达式.作为参考,您可以在此处查看 Haskell 98语法的技术说明,但相关部分是

rhs    ->  = exp [where decls]
       |   gdrhs [where decls]
Run Code Online (Sandbox Code Playgroud)

其中声明定义的右侧可以包含带有可选wherewith声明的表达式,或带有可选with声明的guard右侧where.

如果你需要一个具有两个函数的绑定,那么你必须在同一个范围内定义它,这就是它的工作原理.


但是有一种解决方法.你可以做点什么

foo :: Int
bar :: String
(foo, bar) = (2 * baz, show baz)
    where baz = 1
Run Code Online (Sandbox Code Playgroud)

但我个人更愿意看到baz顶级而不是(foo, bar)顶级.