For the record, I'm a Haskell noob. I'm trying to understand why a range can be declared as
[1..10] -- yields [1,2,3,4,5,6,7,8,9,10]
and not
[10..1] -- yields []
It seems simple enough to implement it like this:
(.:.) :: Enum a => a -> a -> [a]
(.:.) a b =
| a == b = []
| a > b = a : (a - 1) .:. b
| a < b = a : (a + 1) .:. b
What am I not understanding here?
答案 0 :(得分:10)
Try [10,9..1]
instead of [10..1]
[10..1]
desugars to enumFromTo
[10,9..1]
desugars to enumFromThenTo
Observe how the functions behave in 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]
The new behavior that you implemented in (.:.)
will rarely be a desirable default, as lists generated this way can no longer always be assumed to be in ascending order. Hence the necessity to make your descending intention explicit with [x,(pred x)..y]
or enumFromThenTo
.
答案 1 :(得分:6)
几乎总是当你有一个像[1..n]
这样的表达式,并且n
恰好是0时,你想要的值是[]
而不是[1,0]
。例如,考虑
factorial n = product [1..n]
然后我们想要
factorial 0 ~~> product [1..0] ~~> product [] ~~> 1 -- correct
不
factorial 0 ~~> product [1..0] ~~> product [1,0] ~~> 0 -- oops
这就是为什么[m..n]
在m > n
时不会产生降序列表的原因。
(如果m >= n+2
(例如,如果在[1..n]
中,n
为否定)那么它很可能是一个错误条件,可以说[m..n]
应该是错误;但它仍然由语言标准定义为[]
。)