GHC 6.12でDeprecatedになるらしいImpredicative Polymorphismをどうやって書き換えるのか考えてみました。
例えばこんなの。
{-# LANGUAGE ImpredicativeTypes, Rank2Types #-} f :: Maybe (forall a. [a] -> a) -> (Int, Char) f (Just g) = (g [1, 2, 3], g ['a', 'b']) f Nothing = (99, 'z')
のように定義して、
f (Just head) f Nothing
のように呼び出せます。
Impredicative Polymorphismを使わないようにするには、Polymorphic Componentsを使ってnewtypeで型を作って、
{-# LANGUAGE PolymorphicComponents #-} newtype MaybeWrapper = MaybeWrapper (forall a. Maybe ([a] -> a)) f :: MaybeWrapper -> (Int, Char) f (MaybeWrapper g) = (h g [1, 2, 3] 99, h g ['a', 'b'] 'z') where h (Just f) l _ = f l h Nothing _ d = d
のように定義して、
f (MaybeWrapper (Just head)) f (MaybeWrapper Nothing)
のように呼び出せばよいのでしょうか。hに渡した時点で単相型になっていますが、fでパターンマッチしたときには多相型のまま受け取れます。