目前尚不完全清楚您想问什么,以及两种情况下 1 和 2 之间的实际差异是什么,但从基本的数学角度来看:
参数多态函数
f
实际上有类型f :: forall a.a->int
对于 Haskell 所基于的类型化 lambda 演算中的函数来说,它是完全合法的类型。它可以是这样的:
f = λa:Type.λx:a.(body for f)
你怎么获得Double->Int
从中?你apply it to Double
type:
f Double = (λa:Type.λx:a.(body for f)) Double => λx:Double.(body for f|a=Double)
Haskell 在幕后执行这两种操作(类型抽象和类型应用),尽管可以显式声明forall
类型签名的一部分XExplicitForAll
GHC 扩展,并明确地做出Double->Int
的实例f
带类型签名:
f_double :: Double -> Int
f_double = f
高等种类
考虑一个简单的类型:
data Example = IntVal Int | NoVal
(是的Maybe Int
).
Maybe
is a type构造函数,就像IntVal
is a data构造函数。这是完全相同的事情,只是“更高一级”,从某种意义上说Maybe
应用于Type
, 很像IntVal
应用于Int
.
在 lambda 演算中,Maybe
有类型:
Maybe : Type->Type
Haskell 不允许您从类型构造函数中获取类型,但允许您获取kind(这只是一个奇特的名字类型的类型):
:k Maybe
Maybe :: * -> *
So no, Maybe
不是一个type:你不能拥有该类型的对象Maybe
. Maybe
(几乎)是一个从类型到类型的函数,比如IntVal
是一个从值到值的函数。
我们将申请的结果称为Maybe
to String
as Maybe String
,就像我们所说的应用结果IntVal
to 4
as IntVal 4
.