为什么不存在类型的模式匹配?

时间:2017-03-02 09:26:27

标签: haskell

即使没有扩展名ExistentialQuantification,Haskell也支持一些存在类型,通过类型同构,适用于任何类型类C

(forall a. C a => (a -> b))  ~  ((exists a. C a => a) -> b)

因此函数f :: C a => a -> b需要x类型的参数exists a. C a。但是Haskell不允许对某些类型的x模式匹配C(通过一个匹配的_完成,因为类型类通常是无限的。)

这很奇怪,因为存在类型是广义和类型。 Haskell支持使用data关键字的有限和类型,并允许它们的模式匹配。在C ++,Java和C#等语言中,存在类型是接口,它们支持与dynamic_castinstanceof等关键字进行模式匹配。

为什么Haskell没有为上面的f等函数实现模式匹配?

2 个答案:

答案 0 :(得分:8)

Haskell的设计允许类型擦除实现。我们仍然可以运行Haskell而无需在运行时携带所有类型级别的信息。这允许实现减少内存占用。

请注意,程序员仍然可以通过添加Typeable a约束来选择在运行时保留类型信息。然后可以使用cast来模式匹配类型。

此外,无法在运行时对类型执行模式匹配对于保证parametricity / free theorems非常重要。例如,如果我们有多态函数

f :: forall a. a -> a

我们保证f是身份(或无法终止)。这是因为任何此类f必须是自然转换,除了身份之外没有其他选项可用。如果我们可以写

那就不是真的
f x = if a==Int then x+1 else x

如果我们添加Typeable a

,确实可以写出类似的内容

同样,g :: a->a->a必须是投影,而h :: [a]->[a]无法将[True]发送至[False,True]。此外,如果h [1,2]=[2,2,1]则必须h "ab" = "bba"。根据自然性,这些函数必须“统一”地处理所有类型a

答案 1 :(得分:2)

如果你想对类型进行模式匹配,那是不可能的,因为

  1. 有无数种类型可供匹配,因此您的模式永远不会详尽无遗。

  2. 作为一个实现细节,GHC在编译时擦除所有类型信息,因此无论如何都无法实现。 (这可能是由于第1点。)

  3. 您提到OO语言通常具有类似instanceof运算符的功能。您可以使用Typeable类在Haskell中执行此操作。如果某个类型是Typeable的实例,则可以使用Dynamic将其“转换”为toDyn类型。然后,您可以稍后尝试使用fromDynamic将其强制转换,然后返回Maybe。 (或fromDyn,返回默认值。)因此Dynamic类型类似于Java的Object;它可以是任何。通常情况下,这并不是非常严格的限制,通常你不会在Haskell中看到这种编程。

    您还可以使用GADT来表示有限类型的集合,然后您可以将它们进行模式匹配。或者常规数据结构。