[Haskell-cafe] (twice head) && (twice tail)

Greg Buchholz haskell at sleepingsquirrel.org
Sat Nov 11 13:45:24 EST 2006

    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

> 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. 


Greg Buchholz 

More information about the Haskell-Cafe mailing list