以 Haskell 中不起眼的恒等函数为例,
id :: forall a. a -> a
鉴于 Haskell 应该支持隐含的多态性,我应该能够通过类型归属来“限制”id
类型似乎是合理的。(forall a. a -> a) -> (forall b. b -> b)
但这不起作用:
Prelude> id :: (forall a. a -> a) -> (forall b. b -> b)
<interactive>:1:1:
Couldn't match expected type `b -> b'
with actual type `forall a. a -> a'
Expected type: (forall a. a -> a) -> b -> b
Actual type: (forall a. a -> a) -> forall a. a -> a
In the expression: id :: (forall a. a -> a) -> (forall b. b -> b)
In an equation for `it':
it = id :: (forall a. a -> a) -> (forall b. b -> b)
当然可以使用所需的签名定义新的受限形式的身份函数:
restrictedId :: (forall a. a -> a) -> (forall b. b -> b)
restrictedId x = x
然而,根据一般定义它是id
行不通的:
restrictedId :: (forall a. a -> a) -> (forall b. b -> b)
restrictedId = id -- Similar error to above
那么这里发生了什么?似乎它可能与不可预测性的困难有关,但启用-XImpredicativeTypes
没有任何区别。