-1

下面是一个函数的定义:

fmap :: (a -> b) -> f a -> f b

你们能解释一下具体是什么意思吗?我不明白的是f af b为什么可以这样写?我的意思是,为什么它语法正确并且编译良好?

我认为应该只有一个变量(a -> b) -> a -> b(a -> b) -> f -> f其他(a -> b) -> c -> d

再一次,问题不在于函数的含义,而在于语法是否正确。

4

3 回答 3

7

您接受“正常”map功能的签名map :: (a -> b) -> [a] -> [b]吗?

现在假设不是[a]我们写了List a(与 比较Maybe a),所以签名读的是map :: (a -> b) -> List a -> List b。此签名在带有 的表格(a -> b) -> f a -> f bf = List

该函数fmap :: (a -> b) -> f a -> f bmap对其他类型构造函数(如Maybe.

于 2013-07-28T06:44:09.593 回答
4

那么 Haskell[1] 类型签名由 3 个元素组成

  • 类型变量。
    • 它们被隐含地普遍量化。从语法上讲,它们以小写字母开头。
  • 具体类型。
    • 它们是填充类型变量的实际“东西”。它们以大写字母开头。
  • 功能箭头。
    • 这代表了功能。这是咖喱和等等等等。从语法上讲,它是一个箭头。

现在,对于您的示例,我们有 2 个元素。a, b, 和f是类型变量,然后我们有函数箭头。

ab具有 kind *,这意味着它们可以按原样由具体类型实例化。f另一方面,有种类* -> *[2]。这意味着f不能以与 and 相同的方式实例ab。它需要用一个类型实例化,该类型采用一种类型,*然后产生一个具体类型。

例如,Maybe必须先给出另一种类型,比如Int,然后才能构造该类型的值。例如Just 1 :: Maybe Int,但wat :: Maybe没有意义。因此,应用程序f a与将值函数f应用于 value相同a,但类型除外。你甚至有部分应用!

所以读f a -> f b作“一个函数,它将采用某种类型f,将其应用于某种类型a,并返回一个f应用于某种类型的类型值b”。

[1] 哈斯克尔我的意思是香草哈斯克尔。类型运算符、对 N 个类型进行排序等使事情变得复杂。

[2] 这不是正常功能->。它谈论的是类型而不是值。

于 2013-07-28T04:09:01.390 回答
2

Haskell 中的语法Type1 Type2意味着类型的应用。例如,您可能已经看到 type Maybe Integer。它的工作原理Maybe是这样定义的:

data Maybe a = ...

注意类型变量a。这意味着我们必须先应用于Maybe某种类型,然后才能将其用作类型本身。在Maybe Integer中,这a被设置为Integer

现在在问题中,我们有f a,即一个类型变量应用于另一个类型变量。这意味着f可以是Maybe期望应用于另一种类型的a东西,并且可以是Integer本身就是一种类型的东西。

于 2013-07-28T13:05:29.567 回答