継続渡しチックな 存在型 を Haskellで

と、自分でも何を言ってるのか分からねーですが、タイトルに継続と書けばとアクセス数とブクマが増えるのでそう書く(←最低)。あながち遠くはないはずだけど

OCamlHaskellのforall を使うような存在型を直接書く事はできないらしい。 そこで #002 存在型 - KeisukeNakano’s diary では なにやら ランク2多相に CPS風味の方法(二重否定が継続渡しだとかいうアレっぽいですがよくわからない)を使うことで OCamlで存在型を実現している。

…と、id:osiireさんに教えてもらった。osiireさんは普通にこれを使っていたが… いまいち僕はぱっと見理解できなかったので、Haskellで焼き直した。

コード

{-# LANGUAGE RankNTypes #-}

newtype Ext = Ext (forall b. Neg b -> b)
newtype Neg b = K (forall a. Show a => a -> b) 

heterolist :: [Ext]
heterolist = [Ext $ \(K k) -> k 1, Ext $ \(K k) -> k True, Ext $ \(K k) -> k "abc"]

heteroshow :: Ext -> String
heteroshow (Ext f) = (f (K show))

テスト

*Main> map heteroshow heterolist
["1","True","\"abc\""]

ほへー。 なんだかすごい。 双対っぽい。

Haskellで普通のやり方は

こちら > http://d.hatena.ne.jp/syd_syd/20080805/p2