Eva*_*oll 20 haskell types list data-structures
我在理解仿函数方面遇到了问题,特别是LYAH中的具体类型.我相信这是因为我不明白究竟[]
是什么.
fmap :: (a -> b) -> f a -> f b
Run Code Online (Sandbox Code Playgroud)
[]
,类型构造函数?或者,它是一个值构造函数?[] :: [a]
?Maybe
类型构造函数还是Just
值构造函数?
Just
那么为什么会有Just
一个签名Just :: a -> Maybe a
而不是Just :: Maybe a
,换句话说,为什么不[]
打字[] :: a -> [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
它(令人困惑的是,我将授予你)语法重载既是类型构造函数又是值构造函数.
这意味着(值构造函数)[]
具有的类型对于所有类型a
,它都是a
(写入的[a]
)列表.这是因为每种类型都有一个空列表.
[]
没有键入值构造函数,a -> [a]
因为空列表没有元素,因此它不需要a
创建一个空列表a
.相比之下Nothing :: Maybe a
.
LYAH在谈论类型构造[]
有样* -> *
,而不是价值的构造[]
与类型[a]
.
只是为了使事情更明确,这种数据类型:
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"类型构造函数是一种特殊情况,在语言规范中定义.