我需要了解类型的工作方式和解释方式。
例如,如果我们采用地图功能,我们有 map ::(a - > b) - > [a] - >并[b]
那么,我该怎么解释呢?
答案 0 :(得分:4)
->
是函数类型的类型构造函数。它是一个右关联中缀运算符,意味着它从右边组合在一起。这意味着我们可以通过向右侧添加函数的显式分组来重写类型。
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 ~ (->) a b
(此处~
表示类型相同)为
(->) a b
function that takes an "a" and return a "b"
将[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
和b
是类型变量,它们可以采用任何类型,我们称之为多态。有时候,你会在Haskell中看到这个明确写成forall
所以我们可以说:
map
是所有类型a
和b
的多态值,它是一个函数:
a
到b
和a
列表返回到b
列表。 答案 1 :(得分:3)
此签名包含->
这一事实告诉我们这是一个功能。无论在最后->
之后发生什么,都是完全应用后函数的返回类型。让我们来看看各个部分。
(a -> b)
这是第一个参数,它也是一个函数。这意味着map
是一个高阶函数 - 它将一个函数作为其参数之一。 a -> b
本身是一个将类型a
的某些值转换为b
类型值的函数。
[a]
第二个论点。方括号是表示列表的特殊语法。因此,该参数是包含a
类型元素的列表。
[b]
结果的类型。同样,列表,但这次使用类型为b
的元素。
我们现在可以尝试解释这个问题。给定函数a -> b
和a
列表,map
似乎(实际上是)将a
列表转换为{{列表}的函数1}} S上。
以下是一个示例:b
。在这种情况下,map (*2) [1,2,3]
是a
(或其他一些整数类型),每个元素都加倍。 Integer
也是b
,因为Integer
采用相同的返回类型,因此类型变量(*2)
和a
是相同的。不一定是这种情况;我们可以使用不同的函数而不是b
,比如(*2)
,它会产生与show
不同的b
,即a
。
在ghci中尝试一下。您可以直接输入String
并查看结果。您可以通过在该行前加上:t来查询表达式的类型。
要了解更多信息,您应该查找其中一个非凡的入门资源。 LYAH有一整章致力于对类型的基本理解,绝对值得一读!