
Cale Gibbard wrote:
On 09/02/06, Brian Hulley
wrote: Brian Hulley wrote:
f :: forall m. (forall a. a->m a) -> c -> d -> (m c, m d)
Of course this type doesn't work on your original example, since (,) is a type constructor with two parameters, not one, but this type signature does actually work just fine in GHC.
--- data Pair x = Pair x x deriving Show data Id x = Id x deriving Show
f :: forall m c d. (forall a. a -> m a) -> c -> d -> (m c, m d) f g x y = (g x, g y) --- *Main> f (\x -> Pair x x) 3 "hello" (Pair 3 3,Pair "hello" "hello") *Main> f (\x -> Id x) 3 "hello" (Id 3,Id "hello")
Perhaps in practice this kind of workaround is sufficient, although this requires you to put the results into a form that can be syntactically matched against m a. I wonder though if it would be possible to have a type system that would work for my original example by automatically creating internal declarations type T1 a = (a,a) and type T2 a = a so that m would match against T1 and T2 respectively. It is difficult to know if this would be a worthwhile thing to do or if most practical applications of polymorphism in any case involve transformations whose shape can be captured sufficiently with multi-param typeclasses etc. Regards, Brian