There's no (safe) way to go from a -> IO b
to IO (a -> b) which is part of what vtuple does. Consider foo :: Int -> IO String foo 0 = return "zero" foo _ = launchMissles >> return "fired!" How would you implement foo2 :: IO (Int -> String) with the same behavior? You can't; you would somehow need to know the argument the function was called at, and when it was going to be called, to implement foo2. So I think you need a better specification! -- ryan On Wed, Aug 11, 2010 at 8:50 AM, Will Jones <w...@sacharissa.co.uk> wrote: > Hi all, > > I'm trying to write a function (I'll call it `vtuple' for lack of a better > name) > that returns a function that itself returns multiple arguments in the form > of a > tuple. For example: > >> {-# LANGUAGE FlexibleInstances #-} >> {-# LANGUAGE FunctionalDependencies #-} >> {-# LANGUAGE MultiParamTypeClasses #-} > >> f :: Int -> IO () >> f = undefined > >> g :: Int -> Int -> IO () >> g = undefined > >> h :: Int -> Int -> Int -> IO () >> h = undefined > > vtuple f :: IO (Int -> (Int, ())) > vtuple g :: IO (Int -> Int -> (Int, (Int, ()))) > > I've tried to type vtuple using a type class; my current effort is something > like: > >> class VTuple ia ir a r | r -> a, a -> ia where >> vtuple :: (ia -> ir) -> IO (a -> r) > >> instance VTuple Int (IO ()) Int (Int, ()) where >> --vtuple :: (Int -> IO ()) -> IO (Int -> (Int, ())) >> vtuple = undefined > >> instance VTuple ia ir a r >> => VTuple Int (ia -> ir) Int (a -> (Int, r)) where > >> --vtuple :: (Int -> ia -> ir) -> IO (Int -> a -> (Int, r)) >> vtuple = undefined > > But this is problematic, since arrows creep in: > > For one argument (fine): > vtuple :: (Int -> IO ()) -> IO (Int -> (Int, ())) > >> vf :: IO (Int -> (Int, ())) >> vf = vtuple f > > For two arguments (also fine): > vtuple :: (Int -> Int -> IO ()) > -> IO (Int -> Int -> (Int, (Int, ()))) > >> vg :: IO (Int -> Int -> (Int, (Int, ()))) >> vg = vtuple g > > For three (noooo!): > vtuple :: (Int -> Int -> IO ()) > -> IO (Int -> Int -> (Int, (Int -> (Int32, (Int32, ()))))) > > And so on. I've thought about it and it seems impossible to solve this > problem > -- you keep needing to ``split'' the function type one arrow further on. Is > this a job for Template Haskell or is there a solution I'm missing here? > Note > that I'd also like to use types other than Int, but I don't think this is > the > primary complication here (touch wood). > > Any help much appreciated, thanks, > Will > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe