Hi all,<br><br>I'm trying to write a function (I'll call it `vtuple' for lack of a better name)<br>that returns a function that itself returns multiple arguments in the form of a<br>tuple. For example:<br><br>> {-# LANGUAGE FlexibleInstances #-}<br>
> {-# LANGUAGE FunctionalDependencies #-}<br>> {-# LANGUAGE MultiParamTypeClasses #-}<br><br>> f :: Int -> IO ()<br>> f = undefined<br><br>> g :: Int -> Int -> IO ()<br>> g = undefined<br><br>> h :: Int -> Int -> Int -> IO ()<br>
> h = undefined<br><br>vtuple f :: IO (Int -> (Int, ()))<br>vtuple g :: IO (Int -> Int -> (Int, (Int, ())))<br><br>I've tried to type vtuple using a type class; my current effort is something<br>like:<br>
<br>
> class VTuple ia ir a r | r -> a, a -> ia where<br>> vtuple :: (ia -> ir) -> IO (a -> r)<br><br>> instance VTuple Int (IO ()) Int (Int, ()) where<br>> --vtuple :: (Int -> IO ()) -> IO (Int -> (Int, ()))<br>
> vtuple = undefined<br><br>> instance VTuple ia ir a r<br>> => VTuple Int (ia -> ir) Int (a -> (Int, r)) where<br><br>> --vtuple :: (Int -> ia -> ir) -> IO (Int -> a -> (Int, r))<br>
> vtuple = undefined<br><br>But this is problematic, since arrows creep in:<br><br>For one argument (fine):<br> vtuple :: (Int -> IO ()) -> IO (Int -> (Int, ()))<br><br>> vf :: IO (Int -> (Int, ()))<br>
> vf = vtuple f<br><br>For two arguments (also fine):<br> vtuple :: (Int -> Int -> IO ())<br> -> IO (Int -> Int -> (Int, (Int, ())))<br><br>> vg :: IO (Int -> Int -> (Int, (Int, ())))<br>
> vg = vtuple g<br><br>For three (noooo!):<br> vtuple :: (Int -> Int -> IO ())<br> -> IO (Int -> Int -> (Int, (Int -> (Int32, (Int32, ())))))<br><br>And so on. I've thought about it and it seems impossible to solve this problem<br>
-- you keep needing to ``split'' the function type one arrow further on. Is<br>this a job for Template Haskell or is there a solution I'm missing here? Note<br>that I'd also like to use types other than Int, but I don't think this is the<br>
primary complication here (touch wood).<br><br>Any help much appreciated, thanks,<br>Will<br>