Haskell通过支持typeclass特性来实现带约束的泛型接口定义,即基于typeclass的polymorphic function。如果程序中现在存在一个typeclass T,并且存在若干具体类型是T的实例,那么如何用一种类型(指代数数据类型)统一管理所有的T的实例?
在Haskell中需要使用存在性量词,即forall关键词来限定数据构造子的参数为满足typeclass T类型约束的具体type。例如:
{-# LANGUAGE ExistentialQuantification #-}
class T a where
func :: a -> Bool
data D1 = D1
data D2 = D2
instance T D1 where
func _ = False
instance T D2 where
func _ = True
data DataT = forall a. T a => DataT a
d = [DataT D1, DataT D2]
s = fmap (\(DataT x) -> func x) d
上面的例子显示,我们可以使用存在性量词,前置于数据构造子,然后就可以使用泛化的构造参数,共享同一个构造子,实现了对不同类型数据(共同typeclass)的管理。注意,这种情况下,类型DataT的实例仅能够接受模式匹配和符合forall关键词后类型约束的接口。
代码经GHC 7.10版本测试通过。