2014-04-27 152 views
0

我需要了解类型是如何工作和可以解释的。了解Haskell类型

例如,如果我们把地图功能,我们有图::(A - > B) - > [A] - > [B]

好了,我该如何解读?

+2

这是关于Haskell的一个非常基本的问题。你在用什么学习材料?例如,http://learnyouahaskell.com/types-and-typeclasses对Haskell类型表示法有广泛的解释。 –

+0

你为什么问这样一个基本问题?每个Haskell教程都会很快得到你要求的答案。我觉得这是一个家庭作业任务的问题(但我可能是错的)。 –

+0

请阅读Haskell的简介。 – nomen

回答

3

这个签名包含->的事实告诉我们这是一个函数。无论在最后一次->之后发生的是函数的返回类型,一旦完全应用。我们来看看各个部分。

(a -> b) 

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

[a] 

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

[b] 

结果的类型。再次列出一个列表,但这次使用b类型的元素。

现在我们可以尝试对此进行推理。给定一个函数a -> ba,map的列表似乎是(它确实是)将该列表a s变换成列表b s的函数。

下面是一个例子:map (*2) [1,2,3]。在这种情况下,aInteger(或其他整数类型),每个元素都加倍。 b也是Integer,因为(*2)假定返回类型相同,所以在这种情况下类型变量ab是相同的。情况并非如此;我们可以有一个不同的功能,而不是(*2),比如show,它会产生一个不同于ab,即String

用ghci试一下。您可以直接输入map show [1,2,3]并查看结果。您可以通过将:t前置到该行来查询表达式的类型。

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

4

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

map :: (a -> b) -> [a] -> [b] 
map :: (a -> b) -> ([a] -> [b]) 

对于施加到两个参数,xyx * y可以在前缀符号被写为(*) a b操作*中缀表达式。我们可以重写前面的类型,从最外层的->开始,这是中间的一个。

map :: (->) (a -> b) ([a] -> [b]) 

而且我们现在可以为

(->)     a    b 
function that takes an "a" and return 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] ~ (->) [a] [b]

(->)     [  a ]    [  b ] 
function that takes a list of "a"s and returns a list of "b"s 

我们说“从ab功能”速记在类型签名

a S和b s为类型变量“它接受一个a并返回一个b功能”,他们可以承担任何类型,我们称之为多态。偶尔,你会看到这个明确写入在Haskell作为forall所以,我们只能说:

map是各类ab多态值,它是一个功能:

  • 需要一个功能从ab
  • 返回从列表a s到b s列表中的函数。