我是Haskell的新手.有人可以解释为什么定义这样的列表会返回一个空列表
ghci> let myList = [10..1]
ghci> myList
[]
Run Code Online (Sandbox Code Playgroud)
但是这可以正常工作.
ghci> let myList = [10, 9..1]
ghci> myList
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
Run Code Online (Sandbox Code Playgroud)
hvr*_*hvr 37
基本上,因为通过使所有元素少于从(包括)向上计数(具有步长)的结果而[10..1]被转换为其enumFromTo 10 1本身具有创建列表的语义的语义.1+110
而[10, 9..1]被转换为enumFromToThen 10 9 1明确指出计数步长为9-10,即-1(硬编码+1为enumFromTo)
在Haskell报告(6.3.4 Enum类)中可以找到更准确的规范:
enumFrom :: a -> [a] -- [n..]
enumFromThen :: a -> a -> [a] -- [n,n'..]
enumFromTo :: a -> a -> [a] -- [n..m]
enumFromThenTo :: a -> a -> a -> [a] -- [n,n'..m]
Run Code Online (Sandbox Code Playgroud)
对于类型
Int和Integer,枚举函数具有以下含义:
序列
enumFrom e1是列表[e1,e1+1,e1+2,...].序列
enumFromThen e1 e2是列表[e1,e1+i,e1+2i,...],其中增量i是e2-e1.增量可以是零或负数.如果增量为零,则所有列表元素都相同.序列
enumFromTo e1 e3是列表[e1,e1+1,e1+2,...e3].如果列表是空的e1 > e3.序列
enumFromThenTo e1 e2 e3是列表[e1,e1+i,e1+2i,...e3],其中增量i为e2-e1.如果增量为正或零,则列表在下一个元素大于时终止e3; 如果列表是空的e1 > e3.如果增量为负,则列表在下一个元素小于时终止e3; 如果列表是空的e1 < e3.
ham*_*mar 11
算术序列表示法只是Enum该类函数的语法糖.
[a..] = enumFrom a
[a..b] = enumFromTo a b
[a, b..] = enumFromThen a b
[a, b..c] = enumFromThenTo a b c
Run Code Online (Sandbox Code Playgroud)
至于为什么它们没有被定义为自动反转,我只能推测,但这里有一些可能的原因:
如果a和b在其他地方定义,这将是很难告诉一目了然哪个方向[a..b]会去.
它有更好的数学属性来推理.您不必为序列反转时添加特殊情况.