Re: hMapping polymorphic functions

hMapping polymorphic functions is indeed quite challenging, but can be done. That was the topic of the message Type-class overloaded functions: second-order typeclass programming with backtracking http://okmij.org/ftp/Haskell/poly2.txt The challenge is how to avoid specifying the context too early or at all and keep the context to the bare minimum. Your particular case is simple however: applying the function (\x->[x]) that applies literally to any argument type and is defined only by one case:
data FnListify = FnListify
instance TypeCast [a] r => Apply FnListify a r where apply _ x = typeCast [x]
list1 = 'a' :*: "a" :*: True :*: HNil test1 = hMap FnListify list1
*Poly2> test1 "a" :*: (["a"] :*: ([True] :*: HNil)) Within the Poly2 framework, the example becomes
data FnListify = FnListify
instance TypeCast Otherwise r => GFN n FnListify a r instance TypeCast [a] r => Apply (GFnA n FnListify) a r where apply _ x = typeCast [x]
instance TypeCast [a] r => Apply FnListify a r where apply _ x = typeCast [x]
test2 = hMap (GFn FnListify) list1
*Poly2> test2 "a" :*: (["a"] :*: ([True] :*: HNil)) The advantage of making things more complicated than they are is that we can add more clauses to our generic function. For example, we may choose to handle Booleans in a different way, by negating them. We add (perhaps in a different module, so the original code remains as it was)
data OnlyBool instance TypeCast OnlyBool r => GFN Z FnListify a r instance Apply OnlyBool Bool HTrue instance TypeCast HFalse r => Apply OnlyBool a r
instance Apply (GFnA Z FnListify) Bool Bool where apply _ x = not x
and now, *Poly2> test2 "a" :*: (["a"] :*: (False :*: HNil)) P.S. It may be worth sending me a carbon copy (CC) of any question relating to HList, OOHaskell, continuations, etc. I can no longer afford reading every message on Haskell-Cafe (or even every tenth message).
participants (1)
-
oleg@pobox.com