Haskell : Generic Programming

Generic Haskellの資料を見ながら、Generic Programmingのお勉強中。
CleanのGenericsはgeneric functionのindexにkindしか取れないようで。実際に適用されるtypeは、type inferenceに任せるしかなさそう。
でもって、CleanにはAscriptionの構文がないので、前に書いたようにそれようの関数を用意してやらないといけない。
微妙だな。・・・。まあ、type inferenceがあれば、できることに変わりはないといえばそうなのだけれど。

      • -

type inferenceに任せるということはどういうことかというと、

parseString :: String -> Maybe a | gParse{|*|} a
printToString :: a -> String | gPrint{|*|} a

という関数をインポートした次のようなモジュールで、

module parse

import StdEnv, GenPrint, GenParse, OptEnv

Start = (a, b, c)
  where
    a = [1..10]
    b = printToString a
    c = asMaybeIntList $ parseString b

    asMaybeIntList :: (Maybe [Int]) -> Maybe [Int]
    asMaybeIntList a = a

parseStringの返値の型を与えるのに、asMaybeIntListという型を指定するためだけの関数を作ってやるということです。

    c :: Maybe [Int]
    c = parseString b

というように直接注釈をつけてやることもできますが、これはできるところとできないところがあるということで。

      • -

type classと組み合わせると、

generic gEq a :: a a -> Bool

gEqArray :: ({a} -> {a} -> Bool) | == a
gEqArray = gEq{|*->*|} (==)

という書き方が可能。

similar :: ((t Char) -> (t Char) -> Bool) | gEq{|*->*|} t
similar = gEq{|*->*|} sim
  where
    sim a b = (toUpper a) == (toUpper b)

というのも可。