什么是Haskell中的[](列表构造函数)?

Eva*_*oll 20 haskell types list data-structures

我在理解仿函数方面遇到了问题,特别是LYAH中的具体类型.我相信这是因为我不明白究竟[]是什么.

fmap :: (a -> b) -> f a -> f b  
Run Code Online (Sandbox Code Playgroud)
  1. [],类型构造函数?或者,它是一个值构造函数?
  2. 这种类型的含义是什么意思[] :: [a]
  3. 它是Maybe类型构造函数还是Just值构造函数?
    1. 如果是这样,Just那么为什么会有Just一个签名Just :: a -> Maybe a而不是Just :: Maybe a,换句话说,为什么不[]打字[] :: a -> [a]
  4. LYAH说这适用于仿函数:请注意我们如何编写实例Functor [a],因为从fmap ::(a - > b) - > fa - > fb,我们看到f必须是采用一种类型的类型构造函数.[a]已经是一个具体类型(其中包含任何类型的列表),[]而是一个类型构造函数,它接受一种类型并可以生成类型,如[Int],[String]甚至[[String]].我很困惑,虽然它的类型[]意味着它就像[a]LYAH试图得到的文字一样?

yfe*_*lum 22

该类型被描述(在GHCI会话中)为:

$ ghci
Prelude> :info []
data [] a = [] | a : [a] -- Defined 
Run Code Online (Sandbox Code Playgroud)

我们也可以将其视为定义为:

data List a = Nil
            | Cons a (List a)
Run Code Online (Sandbox Code Playgroud)

要么

data List a = EmptyList
            | ListElement a (List a)
Run Code Online (Sandbox Code Playgroud)

键入构造函数

[a]是一种多态数据类型,也可以[] a如上所述编写.这可能被认为是好像List a

在这种情况下,[]是一种类型构造服用一种类型的参数a和返回的类型[] a,其也允许被写成[a].

可以写一个函数的类型,如:

sum :: (Num a) => [a] -> a
Run Code Online (Sandbox Code Playgroud)

数据构造函数

[]是一个数据构造函数,本质上意味着"空列表".此数据构造函数不带任何值参数.

还有另一个数据构造函数,:它将元素添加到另一个列表的前面.此数据构造函数的签名是a : [a]- 它接受一个元素和另一个元素列表,并返回一个结果元素列表.

[]符号也可以用作速记构建一个列表.通常我们会将列表构造为:

myNums = 3 : 2 : 4 : 7 : 12 : 8 : []
Run Code Online (Sandbox Code Playgroud)

这被解释为

myNums = 3 : (2 : (4 : (7 : (12 : (8 : [])))))
Run Code Online (Sandbox Code Playgroud)

但是Haskell允许我们使用速记

myNums = [ 3, 2, 4, 7, 12, 8 ]
Run Code Online (Sandbox Code Playgroud)

作为意义上的等价物,但在外观上略微更好,符号.

暧昧的案例

有一个模糊的案例是常见的:[a].根据上下文,这种表示法可以表示a"s 列表"或"只包含一个元素的列表,即" a.第一个含义是[a]出现在类型中时的预期含义,而第二个含义是[a]出现在值中时的预期含义.


Dou*_*ean 15

  1. 它(令人困惑的是,我将授予你)语法重载既是类型构造函数又是值构造函数.

  2. 这意味着(值构造函数)[]具有的类型对于所有类型a,它都是a(写入的[a])列表.这是因为每种类型都有一个空列表.

  3. []没有键入值构造函数,a -> [a]因为空列表没有元素,因此它不需要a创建一个空列表a.相比之下Nothing :: Maybe a.

  4. LYAH在谈论类型构造[]有样* -> *,而不是价值的构造[]与类型[a].

  • 知道作为一个类型,`[a]`是`[] a`的语法糖可能会有所帮助,这看起来更像是通常为更高级别的类型做的事情. (5认同)

Don*_*art 9

  1. 它是一个类型构造函数(例如[Int]是一个类型),一个数据构造函数([2]是一个列表结构).
  2. 空列表是包含任何类型的列表
  3. [a]就像是一个,[2]就像只是2.
  4. []是零值函数(常量),因此它没有函数类型.


C. *_*ann 5

只是为了使事情更明确,这种数据类型:

data List a = Cons a (List a) 
            | Nil
Run Code Online (Sandbox Code Playgroud)

...具有与内置列表类型相同的结构,但没有(更好,但可能令人困惑)特殊语法.这是一些通信的样子:

  • List= [],类型构造函数* -> *
  • List a= [a],类型与种类*
  • Nil= [],重视与多态类型List a[a]分别
  • Cons= :,分别具有类型a -> List a -> List a和数据的数据构造函数a -> [a] -> [a]
  • Cons 5 Nil= [5]5:[],单个元素列表
  • f Nil = ...= f [] = ...,模式匹配空列表
  • f (Cons x Nil) = ... = f [x] = ...`,模式匹配单元素列表
  • f (Cons x xs) = ...= f (x:xs) = ...,模式匹配非空列表

事实上,如果你问ghci [],它会告诉你几乎相同的定义:

> :i []
data [] a = [] | a : [a]           -- Defined in GHC.Types
Run Code Online (Sandbox Code Playgroud)

但是你不能自己编写这样的定义,因为列表语法及其"outfix"类型构造函数是一种特殊情况,在语言规范中定义.

  • 也许你绊倒的是*数据构造函数*不必将代表所有(或任何)参数的参数带到*类型构造函数*?在'数据中,ab =左a | 右边b`,数据构造函数`Left a`仍然创建一个类型`Either ab`的值,即使没有'b`也没有."Nothing"和"[]"也是如此.你甚至可以拥有像'data NoValue abcdef = Lonely`这样的东西.尽管它没有任何价值,但是"Lonely"仍然被所有这些类型参数的幽灵所困扰,使它与任何不同类型的孤独者不同. (4认同)