理解Haskell类型

理解Haskell类型,haskell,Haskell,我需要了解类型是如何工作的以及如何被解释的 例如,如果我们使用map函数,我们有map::(a->b)->[a]->[b] 那么,我该如何解释呢?这个签名包含->这一事实告诉我们它是一个函数。最后一个->之后的内容是函数完全应用后的返回类型。让我们看一看各个部分 (a -> b) 这是第一个参数,也是一个函数。这意味着map是一个高阶函数——它将函数作为其参数之一a->b本身是一个函数,它将a类型的某些值转换为b类型的某些值 [a] 第二个论点。方括号是表示列表的特殊语法。因此,此参数

我需要了解类型是如何工作的以及如何被解释的

例如,如果我们使用map函数,我们有map::(a->b)->[a]->[b]


那么,我该如何解释呢?

这个签名包含
->
这一事实告诉我们它是一个函数。最后一个
->
之后的内容是函数完全应用后的返回类型。让我们看一看各个部分

(a -> b)
这是第一个参数,也是一个函数。这意味着
map
是一个高阶函数——它将函数作为其参数之一
a->b
本身是一个函数,它将
a
类型的某些值转换为
b
类型的某些值

[a]
第二个论点。方括号是表示列表的特殊语法。因此,此参数是一个包含
a
类型元素的列表

[b]
结果的类型。同样是一个列表,但这次是类型为
b
的元素

[a]
我们现在可以试着解释一下。给定一个函数
a->b
和一个
a
列表,
map
似乎(实际上)是一个将
a
s列表转换为
b
s列表的函数

下面是一个示例:
map(*2)[1,2,3]
。在这种情况下,
a
Integer
(或其他一些整数类型),并且每个元素都加倍
b也为
Integer
,因为
(*2)
采用相同的返回类型,因此在这种情况下,类型变量
a
b
是相同的。情况未必如此;我们可以用一个不同的函数来代替
(*2)
,比如说
show
,它会产生一个与
a
不同的
b
,即
字符串

在ghci中试用。您可以直接键入
map show[1,2,3]
并查看结果。您可以通过在该行前面加上:t来查询表达式的类型


要了解更多信息,您应该查找一个奇妙的入门资源。有一整章致力于对类型的基本理解,绝对值得一读

->
是函数类型的类型构造函数。它是一个右关联中缀运算符,意味着它从右侧分组在一起。这意味着我们可以通过在右侧为函数添加显式分组来重写类型

map :: (a -> b) ->  [a] -> [b]
map :: (a -> b) -> ([a] -> [b])
运算符
*
的中缀表达式应用于两个参数,
x
y
x*y
,可以用前缀表示法写成
(*)a b
。我们可以重写前面的类型,从最外层的代码>代码> ->代码>中间。

map :: (->) (a -> b) ([a] -> [b])
现在我们可以把最后一种翻译成英语了

map ::   (->)                   (a -> b)                 ([a] -> [b])
map is a function that takes a "(a -> b)" and returns a "([a] -> [b])"
其中,我们将
a->b-(>)ab
(此处
~
表示类型等效)解释为

并将
[a]->[b]~-(>)[a][b]
解释为

(->)                  [        a ]               [        b ]
function that takes a list of "a"s and returns a list of "b"s
我们称“从
a
b
的函数”为“接受
a
并返回
b
的函数”的缩写

类型签名中的
a
s和
b
s是类型变量,它们可以采用任何类型,我们称之为多态性。偶尔,您会看到这篇文章在Haskell中被明确地写成
forall

map
是所有类型
a
b
的多态值,这是一个函数:

  • 将函数从
    a
    取到
    b
  • 将函数从
    a
    s列表返回到
    b
    s列表
这是关于Haskell的一个非常基本的问题。你在使用什么学习材料?例如,对Haskell类型表示法有广泛的解释。你为什么问这样一个基本的问题?每个Haskell教程都会很快找到你所问问题的答案。我觉得这是一个家庭作业问题(但我可能错了)。请阅读Haskell的温和介绍。