
Over on comp.lang.functional ( http://xrl.us/s6kv ), Toby Kelsey is wondering about writing a function "twice" that applies a function to an argument two times...
twice' :: (a -> a) -> a -> a twice' f x = f (f x)
...that works for things like "twice succ 0" and "twice tail [1,2,3]", but the type signature means you can't try something like "twice head [[1]]". You can get the "twice head" case to work with a function like...
twice'' :: (forall a. (m a) -> a) -> (m (m b)) -> b twice'' f x = f (f x)
...and if you want something like "twice (flip (:) [])", you'd use...
twice''' :: (forall a. a -> (m a)) -> b -> (m (m b)) twice''' f x = f (f x)
...it seems like those type signatures have at least a passing resemblance, so I was wondering if you could use type classes to combine these functions. I tried something like...
class Twice a b c | a b -> c where twice :: a -> b -> c
instance Twice (a->a) a a where twice f x = f (f x)
instance Twice (forall a. (m a) -> a) (m (m b)) b where twice f x = f (f x)
...but with ghc-6.6 it chokes with... Illegal polymorphic or qualified type: forall a. m a -> a In the instance declaration for `Twice (forall a. (m a) -> a) (m (m b)) b' ...I can't say I'm surprised, but I was wondering if anyone else has thoughts on how this limitation might be worked around. Curious, Greg Buchholz

not a solution to your problem, but covers all your tests, as well as one more that would inevitably have followed:-) cheers, claus
participants (2)
-
Claus Reinke
-
Greg Buchholz