1

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但是,当我尝试加载文件时,这再次在输入上给出解析错误。

4

2 回答 2

4

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

您可以使用let: let 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

再看一遍,我发现我误解了您的代码——您有 3 个wheres,因为您希望每个 s 都应用于前面的函数。where在这种情况下,您必须按照我所说的方式缩进s,例如

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 } } }
}

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

于 2012-11-29T10:08:47.890 回答
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必须相对于它所附加的等式缩进(所以第一个比where缩进更多cprod,第二个where比 缩进更多f,等等)
  • shachaf 的回答在语法上是正确的;但是您的示例代码h使用了x定义的 ingg使用yss定义的 in f,这就是为什么在这种情况下我们确实需要where为每个额外的函数添加一个
于 2012-11-29T10:35:41.580 回答