在haskell中,您可以通过列表理解一次创建多个列表元素吗?
例如,假设我有一个数字列表,我想创建一个包含每个数字乘以2和3的列表。有没有什么方法可以像下面这样做,但是要取回一个数字列表而不是一个数字列表在haskell中,您可以通过列表理解一次创建多个列表元素吗?,haskell,list,list-comprehension,Haskell,List,List Comprehension,例如,假设我有一个数字列表,我想创建一个包含每个数字乘以2和3的列表。有没有什么方法可以像下面这样做,但是要取回一个数字列表而不是一个数字列表 mult_nums = [ [(n*2),(n*3)] | n <- [1..5]] -- this returns [[2,3],[4,6],[6,9],[8,12],[10,15]] -- but we want [2,3,4,6,6,9,8,12,10,15] 你可以使用concat concat [ [(n*2),(n*3)] | n
mult_nums = [ [(n*2),(n*3)] | n <- [1..5]]
-- this returns [[2,3],[4,6],[6,9],[8,12],[10,15]]
-- but we want [2,3,4,6,6,9,8,12,10,15]
你可以使用concat
concat [ [(n*2),(n*3)] | n <- [1..5]]
output: [2,3,4,6,6,9,8,12,10,15]
concat[[(n*2),(n*3)]|n在一些类似的情况下,concat映射也很方便,尽管在这里变化不大:
concatMap (\n -> [n*2,n*3]) [1..5]
concatMap(\n->[n*2,n*3])[1..5]我发现扩展列表理解使其更易于阅读:
[ m | n <- [1..5], m <- [2*n,3*n] ]
表达式concatMap(\m->[m])
将m
包装在一个列表中,以便立即将其展平,它相当于map id
将此与@FunctorSalad的答案进行比较:
mult1 lst = concatMap (\n -> [n*2,n*3]) lst
mult2 lst = concat [ [(n*2),(n*3)] | n <- lst]
我们已经优化了concatMap(\m->[m])
现在@vili的答案是:
mult1 lst = concatMap (\n -> [n*2,n*3]) lst
mult2 lst = concat [ [(n*2),(n*3)] | n <- lst]
在上面的第一个解决方案中,我们不必要地创建了一个列表列表,我们必须concat
away
我不认为有一种解决方案可以使用列表理解,但desugars可以使用mult1
。我的直觉是,Haskell编译器通常足够聪明,所以这并不重要(或者,不必要的concat
由于惰性计算而便宜(而它们在急切的语言中是致命的)).对于实例Monad[]
,(>>=)==翻转concatMap
…克里斯的答案似乎掩盖了这一部分,但这个答案是上面答案的一个子集。
mult2' lst = concat (concatMap (\n -> [[2*n,3*n]]) lst)