Haskell 函子';什么类型的fmap?
关于它的类型,Haskell 函子';什么类型的fmap?,haskell,types,Haskell,Types,关于它的类型,fa和fb告诉了我什么 class Functor f where fmap :: (a -> b) -> f a -> f b 我想我得到了函子标准实例背后的想法。然而,我很难理解fa和f实际上代表了什么 我知道fa和fb只是类型,它们必须包含用于创建它们的类型构造函数和使用的类型参数的信息 f是*->*类型的构造函数吗?(>)r和可能是一样的类型构造函数吗 我知道f a和f b只是类型,它们必须包含创建它们所使用的类型构造函数和所使用的类型参数的信息 很
fa
和fb
告诉了我什么
class Functor f where
fmap :: (a -> b) -> f a -> f b
我想我得到了函子标准实例背后的想法。然而,我很难理解fa
和f
实际上代表了什么
我知道fa
和fb
只是类型,它们必须包含用于创建它们的类型构造函数和使用的类型参数的信息
f
是*->*
类型的构造函数吗?(>)r
和可能是一样的类型构造函数吗
我知道f a和f b只是类型,它们必须包含创建它们所使用的类型构造函数和所使用的类型参数的信息
很好的解释
f
是*->*
类型的构造函数吗
实际上
(>)r
和Maybe一样是类型构造函数吗
实际上,是的:
是的,从某种意义上讲,您可以将其应用于String
和getr->String
,就像您可以将Maybe
应用于String
以获取Maybe String
一样。您可以使用f
任何其他类型的类型
…但不是
不,在丹尼尔·瓦格纳指出的意义上;确切地说,可能
和[]
是类型构造函数,但是(>)r
和或者a
有点像部分应用的类型构造函数。尽管如此,它们还是很好的函子,因为您可以自由地“在”它们内部应用函数,并更改“内容”的类型
(用倒逗号表示的东西是非常不精确的术语。)我(可能有点折磨)的理解是可能和(>)r
都是类型,属于*->*
。或者,报告也将它们标记为类型表达式——但我看不出报告使用这两个术语的方式有什么明显区别,除了表面语法细节(>)
和可能是类型构造函数;类型表达式由类型构造函数和类型变量组合而成
例如,2010年报告第4.1.1节(“种类”)说(我的黑体字):
为确保其有效性,类型表达式被分为不同的类型,可以采用以下两种形式之一:
- 象征∗ 表示所有空类型构造函数的类型
- 如果κ1和κ2是种类,那么κ1→ κ2是一种类型,它接受一种类型类型的κ1并返回一种类型的κ2
第4.3.2节,“实例声明”(粗体):
使类型T成为C类实例的实例
声明称为C-T实例声明,并受以下静态限制:
- 类型在程序中不能多次声明为特定类的实例
- 类和类型必须具有相同的类型;这可通过第4.6节所述的种类推断确定
因此,按照该语言,下面的实例
声明使类型(>)r
成为类函子
的实例:
instance Functor ((->) r) where
fmap f g = f . g
这个术语的有趣之处在于,我们称(>)r
为“类型”,即使Haskell中没有表达式具有该类型,甚至未定义的:
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中的所有声明都必须具有类型*
顺便说一句,从我对依赖类型语言的有限理解来看,其中许多语言缺乏Haskell对术语和类型的明确区分,因此类似于(>)布尔值的表达式是一个函数,它的值是以类型为参数并生成类型作为结果。许多人会调用(>)r
类型构造函数,但“构造函数”的用法可能有点松散。这些人的意思是“某种有箭的东西”。但是报告只为data
或newtype
关键字放入范围的新名称保留了“类型构造函数”——例如可能和StateT
,但也为Int
、Bool
、()
等没有箭头的东西保留了类型构造函数。它类似于“值构造函数”--我们会说,Nothing
是一个构造函数,(,)
是一个构造函数,但(,)5
不是。我认为您应该阅读这篇文章来帮助理解类型签名。