haskell - 让/在列表理解中等效吗?

标签 haskell functional-programming list-comprehension

有没有办法在列表理解中使用 letwhere 或以其他方式定义子表达式,以便它可以在术语和约束中使用?

根据我的实验,进行了以下工作:

[let x = i*i in x | i<-[1..10], i*i > 20]   --good
[i*i | i<-[1..10], let x=i*i in x > 20]     --good

但这些不属于范围:

[let x = i*i in x | i<-[1..10], x > 20]  -- 'x' not in scope error
let x = i*i in [x | i<-[1..10], x > 20]  -- 'i' not in scope error
[x | i<-[1..10], x > 20] where x = i*i   --parse error on 'where'

因此 let 可以在一个地方或另一个地方工作,但不能同时工作!

我发现让它工作的唯一方法(即,避免重复的表达式和可能的评估)是添加一个愚蠢的单例列表,就像我在这里用 x<-[cat i [1..k] 作为列表理解的约束一样:

> let cat x l = foldl1 (++) $ map show [x*i | i<-l]
maximum [x| i<-[1..9999], k<-[2..div 10 $ length $ show i], x<-[cat i [1..k]], sort x == "123456789"]
"932718654"

或者,继续上面的简单示例,

[x | i<-[0..10], x<-[i*i], x > 20] --works

这看起来有点愚蠢,并且稍微缺乏清晰度,但看起来效率并不算太低。不过,如果 letwhere 能够在整个理解过程中发挥作用,那就太好了。这可以吗?

最佳答案

你可以这样写:

[x | i <- [0..10], let x = i*i, x > 20]

注意没有in。您可以在该术语以及 let 后面的任何约束中引用 x。这种形式的 let 对应于 do 表示法中的形式:

do i <- [0..10]
   let x = i*i
   guard (x > 20)
   return x

此处,x 的范围是从 letdo block 末尾的范围。

关于haskell - 让/在列表理解中等效吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6067839/

相关文章:

javascript - 为什么我的reduce 函数中的累加器不接受回调的返回值?

javascript - 如何对数组中的对象使用 javascript reduce 函数来获取字符串值

python - 我有一个 for 循环来创建一个列表,我可以改用列表理解吗?

python - Python 列表理解中的附加条件

Python 列表理解与数据框循环

list - 如何对两个列表的元素求和。 haskell

algorithm - Real World Haskell book - Logger monad 示例的渐近复杂性

java - Frege 中与 Java 的互操作性,尤其是在 IO Monad 中

haskell - 如何从链接列表中删除第 n 个元素?

javascript - 用箭头函数模拟javascript函数