我知道浮点数由于其不精确的性质可能会导致范围内的奇怪行为。
我预计可能存在不精确的值。例如:[0.1,0.3..1]
可能会给[0.1,0.3,0.5,0.7,0.8999999999999999]
代替[0.1,0.3,0.5,0.7,0.9]
然而,除了精度损失之外,我还得到了一个额外的元素:
ghci> [0.1,0.3..1]
[0.1,0.3,0.5,0.7,0.8999999999999999,1.0999999999999999]
这很奇怪,但解释了here。我想我可以这样解决它:
ghci> [0.1,0.3..0.99]
[0.1,0.3,0.5,0.7,0.8999999999999999]
但这有点恶心。也许有一种更清洁的方法。当然,对于这个简单的例子,我可以只使用范围[0.1,0.3..0.9]
一切都很好。
但在更复杂的示例中,我可能不会很快知道(或者如果我很懒的话,想弄清楚)我应该使用的确切上限。那么,我只需制作一个整数范围,然后除以 10,对吧?没有:
ghci> map (/10) [1,3..10]
[0.1,0.3,0.5,0.7,0.9,1.1]
任何浮点函数似乎都会导致此行为:
ghci> map (*1.0) [1,3..10]
[1.0,3.0,5.0,7.0,9.0,11.0]
而非浮动函数则不会:
ghci> map (*1) [1,3..10]
[1,3,5,7,9]
虽然看起来不太可能,但我认为可能是一些懒惰的评估在起作用,并尝试首先强制评估范围:
ghci> let list = [1,3..10] in seq list (map (*1.0) list)
[1.0,3.0,5.0,7.0,9.0,11.0]
显然,使用文字列表而不是范围可以很好地工作:
ghci> map (*1.0) [1,3,5,7,9]
[1.0,3.0,5.0,7.0,9.0]
ghci> let list = [1,3,5,7,9] in seq list (map (*1.0) list)
[1.0,3.0,5.0,7.0,9.0]
它不仅仅是映射:
ghci> last [1,3..10]
9
ghci> 1.0 * (last [1,3..10])
11.0
将函数应用于某个范围的结果会如何影响该范围的实际评估结果?