在Haskell中,为什么这是一个有效的表达式?

时间:2018-10-28 05:04:55

标签: haskell

此表达式似乎无效,因为前两个元素是列表,而最后一个元素是列表。

[1,2,3]:[4,5]:[[]]

但是实际上,它的确等于并且等于:

[[1,2,3],[4,5],[]]

怎么来?

3 个答案:

答案 0 :(得分:4)

考虑:以下内容似乎无效,因为前三个元素是整数,而最后一个是列表:

1 : 2 : 3 : []

但实际上,它确实可以评估!

[1, 2, 3]

或者,更直接地,得到相同的结果:

1 : 2 : [3]

[1,2,3]:[4,5]:[[]]只是[1,2,3] : [4,5] : [] : []

答案 1 :(得分:1)

如果您尝试

:t [[]]

在GHCI中

它给

  

[[a]]

[1,2,3], [4,5][Int]

因此Haskell推断[[a]]的类型为[[Int]]

因此,[Int]:[Int]:[[Int]] = [[Int]]

对应,[1,2,3]:[4,5]:[[]] = [[1,2,3],[4,5],[]]

答案 2 :(得分:0)

这是因为:不会分隔元素,而是将项目放在列表的前面的构造方法(传统上被称为cons)。

Prelude> :i (:)
data [] a = ... | a : [a]       -- Defined in ‘GHC.Types’
infixr 5 :
Prelude> :t (:)
(:) :: a -> [a] -> [a]

因此,右边的值已经是:返回的列表类型。在这种情况下,它们都是[[Int]],并且恰好有一个空列表作为外部列表中的最后一个元素。因为:是右关联的,所以[1,2,3]:[4,5]:[[]][1,2,3]:([4,5]:[[]])[[1,2,3], [4,5], []]等效。

前奏列表类型具有两个构造函数,[](空列表)和:(前缀构造函数)。 [a,b,c]形式是语法糖,如Haskell 2010 Languare Report sections 3.7, Lists的“翻译”框中所指定。

  

[e1, …, ek] = e1 : (e2 : ( … (ek : [])))