2009-11-14 [長年日記]

[Haskell] Impredicative Polymorphism

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でパターンマッチしたときには多相型のまま受け取れます。

[]

トップ «前の日記(2009-11-11) 最新 次の日記(2009-11-21)»