许多静态类型语言具有参数多态性.例如在C#中,可以定义:
T Foo<T>(T x){ return x; }
Run Code Online (Sandbox Code Playgroud)
在呼叫站点中,您可以:
int y = Foo<int>(3);
Run Code Online (Sandbox Code Playgroud)
这些类型有时也像这样写:
Foo :: forall T. T -> T
Run Code Online (Sandbox Code Playgroud)
我听过有人说"forall就像类型级别的lambda抽象".所以Foo是一个函数,它接受一个类型(例如int),并产生一个值(例如int - > int类型的函数).许多语言推断出类型参数,因此您可以编写Foo(3)而不是Foo<int>(3).
假设我们有一个f类型的对象forall T. T -> T.我们可以用这个对象做的是首先通过Q写入传递它f<Q>.然后我们得到一个类型的值Q -> Q.但是,某些f是无效的.例如f:
f<int> = (x => x+1)
f<T> = (x => x)
Run Code Online (Sandbox Code Playgroud)
因此,如果我们"调用",f<int>那么我们会返回一个带有类型的值,int -> int一般来说,如果我们"调用",f<Q>那么我们会返回一个带有类型的值Q -> Q,这样就很好了.但是,人们普遍认为这f不是一种有效的类型forall T. T -> T,因为它根据您传递的类型做了 …
ocaml haskell types existential-type parametric-polymorphism
f1和之间有什么区别f2?
$ ghci -XRankNTypes -XPolyKinds
Prelude> let f1 = undefined :: (forall a m. m a -> Int) -> Int
Prelude> let f2 = undefined :: (forall (a :: k) m. m a -> Int) -> Int
Prelude> :t f1
f1 :: (forall (a :: k) (m :: k -> *). m a -> Int) -> Int
Prelude> :t f2
f2 :: (forall (k :: BOX) (a :: k) (m :: k -> *). m a -> …Run Code Online (Sandbox Code Playgroud)