即使没有扩展ExistentialQuantification,Haskell也支持一些存在类型,通过类型同构,对于任何类型类C,
(forall a. C a => (a -> b)) ~ ((exists a. C a => a) -> b)
Run Code Online (Sandbox Code Playgroud)
所以函数f :: C a => a -> b需要一个x类型的参数exists a. C a.但是Haskell不允许x对某些类型的模式匹配C(通过狂野匹配完成_,因为类型类通常是无限的).
这很奇怪,因为存在类型是广义和类型.Haskell确实支持带有data关键字的有限和类型,并允许它们的模式匹配.在C++,Java和C#等语言中,存在类型是接口,它们支持使用dynamic_cast或等关键字进行模式匹配instanceof.
Haskell没有为f上述函数实现模式匹配的原因吗?
Haskell的设计允许类型擦除实现.我们仍然可以运行Haskell而无需在运行时携带所有类型级别的信息.这允许实现减少内存占用.
请注意,程序员仍然可以通过添加Typeable a约束来选择在运行时保留类型信息.cast然后可以用于模式匹配类型.
此外,不能在运行时对类型执行模式匹配对于保证参数/自由定理是重要的.例如,如果我们有多态函数
f :: forall a. a -> a
Run Code Online (Sandbox Code Playgroud)
我们保证f是身份(或未能终止).这是因为任何此类f必须是自然变换,除了身份之外没有其他选择.如果我们可以写,那就不是真的
f x = if a==Int then x+1 else x
Run Code Online (Sandbox Code Playgroud)
如果我们添加,确实可以写出类似的东西Typeable a.
同样,g :: a->a->a必须是投影,而h :: [a]->[a]不能发送[True]到[False,True].此外,如果h [1,2]=[2,2,1]必要的话h "ab" = "bba".通过自然,这些功能必须在所有类型上"均匀"地工作a.