[英]Strange result of List generation in Haskell
从Haskell的Ranges(GHCi)可以清楚地了解为什么[2, 2..20]
生成无穷大列表。
下一个值是相同的,这就是为什么这个代码产生无穷大列表。
看起来它并不关心限制,因为[2, 2..2]
生成也无限列表。
题:
为什么以下代码[2, 2..(-20)]
生成空列表?
简而言之 :这是预期的行为。
[x, y..z]
表达式是enumFromThenTo xyz
语法糖, enumFromThenTo :: a -> a -> a -> [a]
。
对于Integer
来说,它的实现方式如下:
instance Enum Integer where # ... enumFromThenTo xy lim = enumDeltaToInteger x (yx) lim
所以它将调用enumDeltaToInteger 2 0 (-20)
。 enumDeltaToInteger
用[src]实现 :
enumDeltaToInteger :: Integer -> Integer -> Integer -> [Integer] enumDeltaToInteger x delta lim | delta >= 0 = up_list x delta lim | otherwise = dn_list x delta lim
因此它被认为是up_list
,并且up_list
将增加,直到它达到大于lim
的值:
up_list :: Integer -> Integer -> Integer -> [Integer] up_list x0 delta lim = go (x0 :: Integer) where go x | x > lim = [] | otherwise = x : go (x+delta)
这就是关于Enum
类的Haskell'10报告中的描述:
序列
enumFromThenTo e1 e2 e3
是列表[e1,e1 + i,e1 + 2i,…e3]
,其中增量i
是e2 − e1
。 如果增量为正或零,则当下一个元素大于e3
时,列表终止 ; 如果e1 > e3
则列表为空 。 如果增量为负,则当下一个元素小于e3
时,列表终止; 如果e1 < e3
则列表为空。
所以文档说如果“step”为零或更多,并且e1 > e3
,则结果为空列表。
然而,这确实是一个“棘手”的案例。 我个人同意使用0
的特殊情况作为“步骤”是有意义的(虽然我本身并不是说这比使用up_list
实现更有利)。 然而事情是如何定义的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.