Haskell 为什么列表是*->;*?

Haskell 为什么列表是*->;*?,haskell,Haskell,在GHCI中,使用列表[]上的:info将显示其类型*->* Prelude> :i [] type [] :: * -> * 当我可以构造一个包含多个元素的列表时,例如[1,2,3]列表在Haskell中有特殊的语法,我如何解释这个问题 您可以使用常规语法自己定义一个数据类型,例如list,如下所示 数据列表a=Nil | Cons a(列表a) 现在特别注意,使用此定义,空列表被写入Nil而不是[],并且整数列表的类型被写入list Int而不是[Int] 如果我们看整数列表

在GHCI中,使用列表[]上的:info将显示其类型*->*

Prelude> :i []
type [] :: * -> *

当我可以构造一个包含多个元素的列表时,例如[1,2,3]

列表在Haskell中有特殊的语法,我如何解释这个问题

您可以使用常规语法自己定义一个数据类型,例如list,如下所示

数据列表a=Nil | Cons a(列表a)
现在特别注意,使用此定义,空列表被写入
Nil
而不是
[]
,并且整数列表的类型被写入
list Int
而不是
[Int]

如果我们看整数列表的类型,它由两个组件组成,
List
Int
。单独来看
List
,它是一个“类型构造函数”,一个类型级别的函数,它接受一个本身是类型的参数(例如
Int
),并形成一个新类型
List Int
。在某些情况下,能够在不带参数的情况下谈论
List
,例如作为其他类型构造函数的参数,或作为类型类的参数,例如
Functor
Applicative
,是很有用的。因此,
List
具有种类
*->*
,因为它需要一个参数

对于Haskell的内置列表类型,如上所述,
list Int
通常被写为
[Int]
,但它也可以被写为
[]Int
,事实上,
[]
list
相对应,是指不应用于其参数而编写的列表类型构造函数,因此它也有种类
*->*


元组类型构造函数在Haskell中也有特殊的语法。例如,整数和布尔值的一对通常写为
(Int,Bool)
,但也可以写为
(,)Int Bool
,其中
(,)
是未应用的对类型构造函数,并且具有种类
*->*->*
,因为它需要两个参数。

首先,请忘记那些
*
符号。他们是历史上的怪人;Haskell正在为他们切换到名称
类型
。在GHC-8.x中,您应该打开
-XTypeInType
扩展以允许该操作,并打开
-xnotaristype
以禁用旧语法。然后它就会读出来

> :k []
[] :: Type -> Type
这个函数箭头与列表中要放入多少元素无关,而是关于列表中应该包含哪种类型的元素,而这总是一种类型。该列表类型的列表值当然能够包含该类型的多个元素

       Int ⟼ [Int]        % [3], [74,12,-394], []
      Bool ⟼ [Bool]       % [True], repeat [False]
(Int,Bool) ⟼ [(Int,Bool)] % [(0,False)], [(3,True)]
      Char ⟼ String       % ['y'], "bla bla", ""
与容器相比:异构列表包含多个不同的类型(每种类型只有一个元素):

现在呢

       '[Int] ⟼ HList '[Int]          % HL[3], HL[-394]
          '[] ⟼ HList '[]             % HL[]
'[Int,String] ⟼ HList '[(Int,String)] % HL[(0,"0")], HL[(1,"one")]

命令是
:k[]
:kind[]
[]
具有种类
*->*
(或
类型->类型
),因为它是一个类型构造函数,将一个类型参数作为“列表…”。例如,
:k[Int]
(给定此参数的情况)具有种类
*
(或
类型
)。您也可以像
:k([])Int
那样编写它,使
[]
成为前缀构造函数,之后提供类型参数的语法更像函数应用程序,但在类型级别。这很奇怪。你们有哪个版本的ghc?也许有些“set-X…”选项有效?My
:i[]
打印更有用的信息:
数据[]a=[]|a:[a]--在“GHC.Types”中定义,
,然后是一些关于实例的信息。@SimonShine:您也可以在前缀中编写
[]
,而不带括号:
[]Int
。删除这样的语法糖分可以方便地解释列表的
Monad
Traversable
实例。
       '[Int] ⟼ HList '[Int]          % HL[3], HL[-394]
          '[] ⟼ HList '[]             % HL[]
'[Int,String] ⟼ HList '[(Int,String)] % HL[(0,"0")], HL[(1,"one")]