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
しても違いはありません。