f a
和f b
告诉我它的类型是什么?
class Functor f where
fmap :: (a -> b) -> f a -> f b
我认为我理解了仿函数的标准实例。但是,我很难理解f a
和f
实际代表的内容。
我理解f a
和f b
只是类型,它们必须携带用于创建它们的类型构造函数的信息,并键入所使用的参数。
f
是* -> *
类型的构造函数吗? (->) r
是Maybe
的类型构造函数吗?
答案 0 :(得分:2)
我理解f a和f b只是类型,它们必须携带用于创建它们的类型构造函数的信息并输入所使用的参数。
很好的解释。
f
是* -> *
类型的构造函数吗?
实际上。
(->) r
是类型构造函数,就像是吗?
实际上,是的:
是的,您可以将其应用于类似String
的类型并获取r -> String
,就像您可以将Maybe
应用于String
以获取{{1 }}。您可以使用Maybe String
从任何其他类型为您提供类型的任何内容。
..但没有...
不,丹尼尔瓦格纳指出的意义;确切地说,f
和Maybe
是类型构造函数,但[]
和(->) r
有点像部分应用的类型构造函数。然而,他们制作好的仿函数,因为你可以自由地在它们里面应用函数并改变“内容”的类型。
(引号中的东西是非常手工制作的不精确的术语。)
答案 1 :(得分:1)
chapter 4 of the Haskell 2010 Report的Maybe
和(->) r
* -> *
和(->)
都是类型,属于Maybe
,我的(可能有点折磨)阅读{{3}}。或者,报告也将它们标记为类型表达式 - 但我无法看出报告如何使用这两个术语的明显差异,除了表面语法细节。 instance
和instance
是类型构造函数;类型表达式由类型构造函数和类型变量组合而成。
例如,2010年报告的第4.1.1节(“种类”)说(我的粗体字):
为了确保它们有效,类型表达式被分类为不同的种,它们采用两种可能的形式之一:
- 符号*表示所有nullary类型构造函数的种类。
- 如果κ1和κ2是种类,则κ1→κ2是类型的种类,它采用类型κ1的类型并返回类型κ2。
第4.3.2节“实例声明”(我的粗体字):
使{strong>类型 T 成为 C 类实例的
(->) r
声明称为 CT实例声明并受这些静态限制的约束:
- 在程序中,类型不能多次声明为特定类的实例。
- 班级和类型必须相同;这可以使用第4.6节中描述的类推理来确定。
通过该语言,以下Functor
声明使类型 instance Functor ((->) r) where
fmap f g = f . g
成为类(->) r
的实例:
undefined
关于这个术语的有趣之处在于我们将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
-}
称为“类型”,即使Haskell中没有具有该类型的表达式 - 甚至不*
:
(->) Boolean
但我认为这不是什么大问题。基本上,Haskell中的所有声明都必须具有类型{{1}}。
作为旁注,根据我对依赖类型语言的有限理解,其中许多缺乏Haskell在术语和类型之间的明确区分,因此{{1}}之类的东西是一个表达式,其值是一个类型的函数作为其参数并生成一个类型作为结果。