具有foldr和'where'的haskell语法

时间:2012-11-29 09:59:31

标签: haskell syntax

foldr (+) 0 [1,2]返回3

我怎么能用'where'来写呢?

foldr f 0 [1,2] where f = (+)返回"parse error on input 'where'"

编辑: 实际上,我正在尝试制作笛卡尔积,如示例

cprod = foldr f [[ ]]
where f xs yss = foldr g [ ] xs
where g x zss = foldr h zss yss
where h ys uss = (x : ys) : uss

但是,当我尝试加载文件时,这会再次在输入where上出现解析错误。

2 个答案:

答案 0 :(得分:4)

... where ...不是表达式。 where与绑定相关联,而不是表达式。

您可以使用letlet f = (+) in foldr f 0 [1,2],也可以将其用于绑定:x = foldr f 0 [1,2] where f = (+)


以下是您编辑的代码的语法上有效的版本(它仍然被破坏,但这不再是语法问题:-))。您只想在每个绑定中使用一个where,并且希望where比函数体更加缩进。

cprod = foldr f [[ ]]
  where
    f xs yss = foldr g [ ] xs
    g x zss = foldr h zss yss
    h ys uss = (x : ys) : uss

再看一遍,我发现我误解了你的代码 - 你有三个where因为你希望每个代码都适用于以前的函数。在这种情况下,你必须按照我所说的方式缩进where,例如

cprod = foldr f [[ ]]
  where f xs yss = foldr g [ ] xs
          where g x zss = foldr h zss yss
                  where h ys uss = (x : ys) : uss

如果您坚持使用where这样且不喜欢深度缩进的代码,则可以使用显式{} / ;而不是布局。一个极端的例子是

{
cprod = foldr f [[ ]]
where { f xs yss = foldr g [ ] xs
where { g x zss = foldr h zss yss
where { h ys uss = (x : ys) : uss } } }
}

但这通常不被认为是好的风格。

答案 1 :(得分:3)

为了响应您的编辑,您的代码应为

cprod = foldr f [[ ]]
  where f xs yss = foldr g [ ] xs
          where g x zss = foldr h zss yss
                  where h ys uss = (x : ys) : uss

重要的是:

  • where附加到等式,而不附加到表达式
  • where必须相对于其附加的等式缩进(因此第一个wherecprod缩进得更多,第二个where缩进比f更多{1}}等)
  • shachaf的答案在语法上是正确的;但是您的示例代码h使用x中定义的gg使用yss中定义的f,这就是为什么在这种情况下,我们确实需要额外的where每个额外的功能