为了记录,我是一个Haskell noob.我试图理解为什么范围可以声明为
[1..10] -- yields [1,2,3,4,5,6,7,8,9,10]
Run Code Online (Sandbox Code Playgroud)
并不是
[10..1] -- yields []
Run Code Online (Sandbox Code Playgroud)
看起来很简单,就像这样实现它:
(.:.) :: Enum a => a -> a -> [a]
(.:.) a b =
| a == b = []
| a > b = a : (a - 1) .:. b
| a < b = a : (a + 1) .:. b
Run Code Online (Sandbox Code Playgroud)
我在这里不理解什么?
rec*_*nja 10
尝试[10,9..1]而不是[10..1]
[10..1] des to to to enumFromTo
[10,9..1] des to to to enumFromThenTo
观察GHCI中函数的行为:
Prelude> [10..1]
[]
Prelude> [10,9..1]
[10,9,8,7,6,5,4,3,2,1]
Prelude> :t enumFromTo
enumFromTo :: Enum a => a -> a -> [a]
Prelude> :t enumFromThenTo
enumFromThenTo :: Enum a => a -> a -> a -> [a]
Prelude> enumFromTo 10 1
[]
Prelude> :t enumFromThenTo 10 9 1
[10,9,8,7,6,5,4,3,2,1]
Run Code Online (Sandbox Code Playgroud)
您实现的新行为(.:.)很少是理想的默认行为,因为以这种方式生成的列表不能再始终假定为升序.因此,必须使用或明确降低意图.[x,(pred x)..y]enumFromThenTo
几乎总是当你有一个类似的表达式[1..n],并且n碰巧是0时,你想要的是值[]而不是[1,0].例如考虑
factorial n = product [1..n]
Run Code Online (Sandbox Code Playgroud)
然后我们想要
factorial 0 ~~> product [1..0] ~~> product [] ~~> 1 -- correct
Run Code Online (Sandbox Code Playgroud)
不
factorial 0 ~~> product [1..0] ~~> product [1,0] ~~> 0 -- oops
Run Code Online (Sandbox Code Playgroud)
这就是为什么[m..n]不生成降序列表的原因m > n.
(如果m >= n+2(例如,如果in [1..n],n则为负数)那么它很可能是一个错误条件,并且可能[m..n]应该是一个错误;但它仍然由语言标准定义[].)