当长度不到3次以下无限列表时,我该如何总和列表列表?
我的代码正在起作用,但不适合无尽的列表。我该如何使其工作?
sumsOf :: Num a => [[a]] -> [a]
sumsOf a = map sum [ x | x <- a , length x < 3]
示例:
sumsOf [[],[1,2,4],[],[6]] == [0,0,6]
sumsOf [[1],[8],[6],[],[9,9]] == [1,8,6,0,18]
sumsOf [[1,2,9,10],[7,8,9],[6,9,4,2,0],[9,9,9]] == []
sumsOf [[1..],[7..],[6..],[9..],[10..],[100..]] == []
sumsOf [[1,2], [1..], [], [4]] == [3,0,4]
My code is working but not for endless lists. How can I make it work ?
sumsOf :: Num a => [[a]] -> [a]
sumsOf a = map sum [ x | x <- a , length x < 3]
Examples :
sumsOf [[],[1,2,4],[],[6]] == [0,0,6]
sumsOf [[1],[8],[6],[],[9,9]] == [1,8,6,0,18]
sumsOf [[1,2,9,10],[7,8,9],[6,9,4,2,0],[9,9,9]] == []
sumsOf [[1..],[7..],[6..],[9..],[10..],[100..]] == []
sumsOf [[1,2], [1..], [], [4]] == [3,0,4]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
长度
是您应该按照经验的列表函数之一从不使用使用,除非您确切地知道为什么还可以。 (另一个是head
和!!
。)这不仅是因为它与无限列表不起作用,还因为它通常完全不必要的 o ( n )在整个列表上进行遍历。即使您以后需要遍历它,这两次也可能会带来很大的性能差异。在这种情况下,请考虑您真正需要的内容:
sum
避免进入漫长或无限列表,而是在两个元素后放弃。实际上,这可以以一种愚蠢的疲惫方式实现:为了使其对任何最大长度进行一般性,您可以使用递归:
...但是,这不是一个很好的实现,原因有两个:它会以负面的论点炸毁,并且不是尾部递归。一个更好的,尽管有点麻烦,但版本会
更优雅,是使用标准功能来获取最大可用元素的计数,并查看是否剩下任何东西:
...或,某些等效的形式,
或者
您可以只是可以在整个给定的列表中绘制该图,并收集成功的所有结果。
length
is one of the list functions that you should as a rule of thumb never use except when you know exactly why it's ok. (The other beinghead
and!!
.) It's not just because it doesn't work with infinite lists, but also because it does a usually completely unnecessary O(n) traversal over the entire list. Even if you need to traverse it anyway later, doing it twice can make a big performance difference.In this case think about what you really need: a
sum
that avoids going into an long or infinite list but instead gives up after two elements. That could actually be implemented in a stupid exhaustion way:To make it general for any max-length, you could use recursion:
...but that's not such a good implementation, for two reasons: it blows up with negative arguments, and it isn't tail recursive. A better, albeit a bit cumbersome, version would be
A bit more elegant is to use a standard function to take the max usable count of elements, and see if anything remains:
...or, some equivalent forms,
or
Then you can just map that over the entire given list and gather all the result that succeeded.
简单液体解决方案:
您只关心长度是否小于3,因此,如果您将输入列表截断为3个元素,则结果不会更改:
因此,这很容易通过无限列表解决问题。
以稍微惯用的方式:
唯一的缺点是库函数
tot
必须复制列表节点。N.1.8e9-在评论中提到的一个想法,通过编写一些
boundedlength
函数,可以使某些内容更有效,以最多返回k <
/code>,例如这样:在这种情况下,我们的
sumsof
函数最终以:Easy-lazy solution:
You are only concerned about whether the length is less than 3, so the result is not changed if you truncate your input list at 3 elements:
So this readily solves the problem with unlimited lists.
In slightly more idiomatic fashion:
The sole drawback is that library function
take
has to duplicate the list nodes.An idea mentioned in a comment by n.1.8e9-where's-my-sharem: it is possible to have something a bit more efficient, by writing some
boundedLength
function that returns at mostk
, for example like this:In that case, our
sumsOf
function ends up as: