Functor的fmap讲述了什么类型? [英] What does Functor's fmap tell about types?
问题描述
fb
告诉我它的类型?
class Functor f其中
fmap ::(a - > b) - > f a - > f b
我想到了一个函数的标准实例背后的想法。然而,我很难理解 fa
和 f
实际上代表了什么。
据我所知, fa
和 fb
只是类型,它们必须携带信息构造函数是什么类型用于创建它们并输入使用的参数。
$ b $ f
类型的类型构造函数 * - > *
? ( - >)r
类型构造函数就像 Maybe 是?
例如,2010年报告的4.1.1节(种类)表示(我的粗体) p>
为了确保它们有效,类型表达式被分为不同的类型,它们采用以下两种可能的形式之一:
$ b
- 符号*表示所有无类型构造函数的类型。
- 如果κ1和κ2是类型,那么κ1→κ2是类型的类型,它们采用类型为κ1的类型并返回类型为κ2的类型
。
第4.3.2节实例声明(粗体):
使类型 T 成为类的实例的
实例声明> C 被称为 CT实例声明,并受以下静态限制:
- 类型不能在程序中多次声明为特定类的实例。
- 类和类型必须具有相同的类型;这可以使用第4.6节中描述的类推理来确定。
因此,按照这种语言,下面的instance
声明使得类型( - >)r
成为一个实例($ - $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ r)其中
fmap fg = f。 g
这个术语的有趣之处在于我们称之为
( - > )r
一个类型,尽管Haskell中没有表达式具有该类型 - 甚至没有undefined
:foo ::( - >)r
foo =未定义
{ -
[1 1]编译Main(../src/scratch.hs,解释)
../src/scratch.hs:1:8:
期望多一个参数到`( - > ;)r'
在`foo'的签名中:foo ::( - >)r
- }
但我认为这不是什么大不了的事情。基本上,Haskell中的所有声明都必须具有类型
*
。
这些语言中很多都缺乏Haskell在术语和类型之间的明确区分,所以像
( - >)布尔
这样的表达式的值是一个函数,一个类型作为它的参数,并产生一个类型作为它的结果。What does
f a
andf b
tell me about its type?class Functor f where fmap :: (a -> b) -> f a -> f b
I think I get the idea behind standard instances of a functor. However I'm having hard time understanding what
f a
andf
actually represent.I understand that
f a
andf b
are just types and they must carry information what type constructor was used to create them and type arguments that were used.Is
f
a type constructor of kind* -> *
? Is(->) r
a type constructor just likeMaybe
is?解决方案My (possibly mildly tortured) reading of chapter 4 of the Haskell 2010 Report is that
Maybe
and(->) r
are both types, of kind* -> *
. Alternatively, the Report also labels them as type expressions—but I can't discern a firm difference in how the Report uses the two terms, except perhaps for surface syntax details.(->)
andMaybe
are type constructors; type expressions are assembled from type constructors and type variables.For example, section 4.1.1 ("Kinds") of the 2010 report says (my boldface):
To ensure that they are valid, type expressions are classified into different kinds, which take one of two possible forms:
- The symbol ∗ represents the kind of all nullary type constructors.
- If κ1 and κ2 are kinds, then κ1 → κ2 is the kind of types that take a type of kind κ1 and return a type of kind κ2.
Section 4.3.2, "Instance Declarations" (my boldface):
An
instance
declaration that makes the type T to be an instance of class C is called a C-T instance declaration and is subject to these static restrictions:
- A type may not be declared as an instance of a particular class more than once in the program.
- The class and type must have the same kind; this can be determined using kind inference as described in Section 4.6.
So going by that language, the following
instance
declaration makes the type(->) r
to be an instance of the classFunctor
:instance Functor ((->) r) where fmap f g = f . g
The funny thing about this terminology is that we call
(->) r
a "type" even though there are no expressions in Haskell that have that type—not evenundefined
:foo :: (->) r foo = undefined {- [1 of 1] Compiling Main ( ../src/scratch.hs, interpreted ) ../src/scratch.hs:1:8: Expecting one more argument to `(->) r' In the type signature for `foo': foo :: (->) r -}
But I think that's not a big deal. Basically, all declarations in Haskell must have types of kind
*
.As a side note, from my limited understanding of dependently typed languages, many of these lack Haskell's firm distinction between terms and types, so that something like
(->) Boolean
is an expression whose value is a function that takes a type as its argument and produces a type as its result.这篇关于Functor的fmap讲述了什么类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!