On Tue, Nov 18, 2003 at 05:56:19PM -0800, oleg@pobox.com wrote:
Abraham Egnor wrote:
The classic way to write a lift function for tuples is, of course:
liftTup f (a, b) = (f a, f b)
which has a type of (a -> b) -> (a, a) -> (b, b). I've been wondering if it would be possible to write a function that doesn't require the types in the tuple to be the same, just that the types in the second tuple are the result of applying the type transformation implied in the function to be lifted to the types in the first tuple.
Well, it is possible in Haskell. It works even in Hugs!
{-# OPTIONS -fglasgow-exts -fallow-undecidable-instances #-}
class Funnable a b | a->b where f:: a -> b
instance Funnable Bool Int where f = fromEnum instance Funnable Char Float where f = fromRational . toRational . fromEnum
class LP a b c d where liftf:: (a, b) -> (c, d)
instance (Funnable a c, Funnable b d) => LP a b c d where liftf (a,b) = (f a, f b)
Main> liftf (True,'z') (1,122.0)
This seems different from what Abraham Egnor asked for, because it allows one to provide many different implementations for f. It corresponds more closely to
liftTup' (f1, f2) (a, b) = (f1 a, f2 b)
which is of course typable with in Haskell. Main> liftTup' (fromEnum, fromRational . toRational . fromEnum) (1, 122.0) (1,122.0) -- Sebastien