If you need real n-tuples (and not just some other data that is semantically equivalent), this would be cumbersome without Template Haskell.
For example, if you want to convert
data Foo = Foo Int String Int data Bar = Bar String String Int Int
in
type FooTuple = (Int, String, Int) type BarTuple = (String, String, Int, Int)
both GHC.Generics and SYB will be problematic because the type of the result must be different depending on the fields of the data type. Despite the fact that both are "tuples" calle, (Int, String, Int) and (String, String, Int, Int) are completely separate types, and there are no convenient ways to work with n-arity tuples in a general way. Here is one way to achieve the above using GHC.Generics :
{-
The above works, but it requires a lot of work (and I could not quickly figure out if this can be done without using UndecidableInstances ).
Now, what you really want to do is probably just skip the tuples and use generics to directly convert to CSV. I assume that you are using csv-conduit and want to generate instances of the ToRecord class.
Here is an example of this
{-
And now you can easily instantiate your custom types.
data Foo = Foo Int String Int deriving (Generic) data Bar = Bar String String Int Int deriving (Generic) instance ToRecord Foo where toRecord = genericToRecord instance ToRecord Bar where toRecord = genericToRecord
In response to your updated question: you might be interested in the tuple package (and especially Curry ), which contains implementations for uncurryN and curryN for tuples up to 15 elements long.
shang
source share