通过使用map,concat替换3参数列表-综合 [英] Replace a 3 parameter list-comprehension by using map, concat

查看:63
本文介绍了通过使用map,concat替换3参数列表-综合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对列表理解有一些了解.我知道该表达方式:

I have some understanding of list comprehension. I understand that the expression:

[x * x | x <- [1..10]]
should output [1,4,9,16,25,36,49,64,81,100]

并且该表达式的效果与:

and that the effect of that expression is the same as:

map power [1..10]
power x = x * x

现在,我必须找出用于以下功能的另一种方法(与上述方法一样):

Now, I have to find out the other method (just like the above) for the following function:

[(x,y+z) | x <- [1..10], y <- [1..x], z <- [1..y]]

我无法无误地自己弄清楚,请帮助我

I can't figure it out by myself without errors, please help me

推荐答案

Haskell报告告诉我们如何翻译列表理解:

The Haskell Report tells us how to translate list comprehensions:

[ e | True ]         = [e]
[ e | q ]            = [ e | q, True ]
[ e | b, Q ]         = if b then [ e | Q ] else []
[ e | p <- l, Q ]    = let ok p = [ e | Q ]
                           ok _ = []
                       in concatMap ok l
[ e | let decls, Q ] = let decls in [ e | Q ]

由于您的列表理解仅使用不可辩驳的模式(即永不失败的模式),因此上面的第四个子句在某种程度上进行了简化:

Since your list comprehension only uses irrefutable patterns (that is, patterns that never fail), the fourth clause above simplifies somewhat:

[ e | p <- l, Q ]    = concatMap (\p -> [ e | Q ]) l

为了简洁起见,我将使用此版本,但真正的派生应使用报告中的定义. (作业:尝试真正的翻译,并检查最后是否得到相同的东西".)让我们尝试一下吧?

I'll use this version for concision, but a true derivation should use the definition from the Report. (Homework: try the real translation, and check that you get the "same thing" in the end.) Let's try it, shall we?

  [(x,y+z) | x <- [1..10], y <- [1..x], z <- [1..y]]
= concatMap (\x -> [(x,y+z) | y <- [1..x], z <- [1..y]] [1..10]
= concatMap (\x -> concatMap (\y -> [(x,y+z) | z <- [1..y]]) [1..x]) [1..10]
= concatMap (\x -> concatMap (\y -> [(x,y+z) | z <- [1..y], True]) [1..x]) [1..10]
= concatMap (\x -> concatMap (\y -> concatMap (\z -> [(x,y+z) | True]) [1..y]) [1..x]) [1..10]
= concatMap (\x -> concatMap (\y -> concatMap (\z -> [(x,y+z)]) [1..y]) [1..x]) [1..10]

我们终于有了一个没有列表理解的版本.

And we're finally at a version that has no list comprehensions.

如果您对monad感到满意,则还可以通过观察concatMap是列表(>>=)函数的翻转版本来深入了解此表达式的行为;此外,[e]类似于列表的return e.因此,用monad运算符重写:

If you're comfortable with monads, then you can also gain insight into the behavior of this expression by observing that concatMap is a flipped version of the list's (>>=) function; moreover, [e] is like the list's return e. So, rewriting with monad operators:

= [1..10] >>= \x ->
  [1..x]  >>= \y ->
  [1..y]  >>= \z ->
  return (x,y+z)

这篇关于通过使用map,concat替换3参数列表-综合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆