List Haskell中的递减范围
我对哈斯克尔很陌生。有人能解释一下为什么这样定义一个列表会返回一个空列表吗List Haskell中的递减范围,list,haskell,List,Haskell,我对哈斯克尔很陌生。有人能解释一下为什么这样定义一个列表会返回一个空列表吗 ghci> let myList = [10..1] ghci> myList [] 然而,这是正确的 ghci> let myList = [10, 9..1] ghci> myList [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] 基本上,因为[10..1]被翻译成enumFromTo 10 1,它本身的语义是通过从(包括)10向上计数(步长+1)得到小于1的所有
ghci> let myList = [10..1]
ghci> myList
[]
然而,这是正确的
ghci> let myList = [10, 9..1]
ghci> myList
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
基本上,因为
[10..1]
被翻译成enumFromTo 10 1
,它本身的语义是通过从(包括)10
向上计数(步长+1
)得到小于1
的所有元素来创建一个列表
而[10,9..1]
被翻译成enumFromToThen 10 9 1
,它明确规定了计数步长为9-10
,即-1
(对于enumFromTo
,它被硬编码为+1
)
更准确的规范可在Haskell报告(6.3.4枚举类)中找到:
对于类型Int
和Integer
,枚举函数具有以下含义:
- 来自e1的序列
是列表enumfrome1
[e1,e1+1,e1+2,…]
- 序列
是列表enumFromThen e1 e2
,其中增量i为e2-e1。增量可以是零或负。如果增量为零,则所有列表元素都相同[e1,e1+i,e1+2i,…]
- 序列
是列表enumFromTo e1 e3
。如果[e1,e1+1,e1+2,…e3]
,则列表为空e1>e3
- 从枚举到e1 e2 e3的序列
是列表
,其中增量[e1,e1+i,e1+2i,…e3]
,是i
。如果增量为正或零,则当下一个元素大于e3时,列表终止;如果e2-e1
,则列表为空。如果增量为负值,则当下一个元素小于e1>e3
时,列表终止;如果e3
,则列表为空e1
基本上,因为
[10..1]
被翻译成enumFromTo 10 1
,它本身的语义是通过从(包括)10
向上计数(步长+1
)得到小于1
的所有元素来创建一个列表
而[10,9..1]
被翻译成enumFromToThen 10 9 1
,它明确规定了计数步长为9-10
,即-1
(对于enumFromTo
,它被硬编码为+1
)
更准确的规范可在Haskell报告(6.3.4枚举类)中找到:
对于类型Int
和Integer
,枚举函数具有以下含义:
- 来自e1的序列
是列表enumfrome1
[e1,e1+1,e1+2,…]
- 序列
是列表enumFromThen e1 e2
,其中增量i为e2-e1。增量可以是零或负。如果增量为零,则所有列表元素都相同[e1,e1+i,e1+2i,…]
- 序列
是列表enumFromTo e1 e3
。如果[e1,e1+1,e1+2,…e3]
,则列表为空e1>e3
- 从枚举到e1 e2 e3的序列
是列表
,其中增量[e1,e1+i,e1+2i,…e3]
,是i
。如果增量为正或零,则当下一个元素大于e3时,列表终止;如果e2-e1
,则列表为空。如果增量为负值,则当下一个元素小于e1>e3
时,列表终止;如果e3
,则列表为空e1
算术序列表示法只是类中函数的语法糖 至于为什么它们没有被定义为自动反转,我只能推测,但以下是一些可能的原因:
- 如果在别处定义了
和a
,那么很难一目了然地判断b
将朝哪个方向发展[a..b]
- 它有更好的数学性质来推理。您不必为顺序颠倒添加特殊情况
- 如果在别处定义了
和a
,那么很难一目了然地判断b
将朝哪个方向发展[a..b]
- 它有更好的数学性质来推理。您不必为顺序颠倒添加特殊情况
a
到b
的列表,而不管a
,您都可以使用以下命令:
[a,a+(signum$b-a)…b]
如果要生成从a
到b
的列表,无论a
,都可以使用以下命令:
[a,a+(signum$b-a)…b]
适用于新手
要列出从20到1的所有数字,你不能只做
[20..1]
您必须这样指定:
[20,19..1]
适用于新手
要列出从20到1的所有数字,你不能只做
[20..1]
您必须这样指定:
[20,19..1]
谢谢,这很有道理。乍一看,我认为这是一个相当愚蠢的符号,但现在我可以看到,它使得定义范围内的步长大小成为可能。很酷!现在对哈斯克尔非常兴奋:)谢谢,这是有道理的。乍一看,我认为这是一个相当愚蠢的符号,但现在我可以看到,它使得定义范围内的步长大小成为可能。很酷!现在对Haskell非常兴奋:)注意,如果a
enumFrom :: a -> [a] -- [n..]
enumFromThen :: a -> a -> [a] -- [n,n'..]
enumFromTo :: a -> a -> [a] -- [n..m]
enumFromThenTo :: a -> a -> a -> [a] -- [n,n'..m]
[a..] = enumFrom a
[a..b] = enumFromTo a b
[a, b..] = enumFromThen a b
[a, b..c] = enumFromThenTo a b c