一般来说,我想知道是否有一种方法可以编写通用折叠来概括应用以下forall
类型的函数:
f :: forall a. Data (D a) => D a -> b
给定一些数据类型D
(instance Data (D a)
可能对 有约束a
)。具体来说,考虑一些简单的事情False `mkQ` isJust
,或者一般来说,对更高种类数据类型的构造函数的查询。类似地,考虑一个mkT (const Nothing)
只影响一种特定的高级类型的转换。
如果没有明确的类型签名,它们就会失败No instance for Typeable a0
,这可能是工作中的单态限制。很公平。但是,如果我们添加显式类型签名:
t :: GenericT
t = mkT (const Nothing :: forall a. Data a => Maybe a -> Maybe a)
q :: GenericQ Bool
q = False `mkQ` (isJust :: forall a. Data a => Maybe a -> Bool)
相反,我们被告知forall
外部签名的类型不明确:
Could not deduce (Typeable a0)
arising from a use of ‘mkT’
from the context: Data a
bound by the type signature for:
t :: GenericT
The type variable ‘a0’ is ambiguous
我无法解决这个问题。如果我真的正确理解那a0
是变量t :: forall a0. Data a0 => a0 -> a0
,它怎么比说更模棱两可mkT not
?如果有的话,我本来会mkT
抱怨的,因为它是与isJust
. 此外,这些函数比具体类型的分支更具多态性。
我很想知道这是否是证明内部约束的限制isJust :: Data a => ...
——我的理解是,任何类型的实例Data
都Maybe a
必须Data a
由实例约束有效instance Data a => Data (Maybe a)
。