Of course, producing a Cartesian product of heterogeneous lists can be done in a number of way in Haskell, such as:
[(x,y) | x <- [1,2,3], y <- [4,5,6]]
or
(,) <$> [1,2,3] <*> [4,5,6]
But what I want is a function like this:
heteroCartesian ::
(a1, a2, ... , an) ->
(b1, b2, ... , bn) ->
((a1,b1), (a1,b2), ... , (a1,bn), (a2,b1), (a2,b2), ... , (a2,bn), (an,b1), ... ,(an,b2), ... , (an,bn))
So I can do something like this:
f (1,'a',True) (2,'b') ==
((1,2),(1,'b'),('a',2),('a','b'),(True,2),(True,'b'))
I don't mind whether I'm using tuples or something else, but I need to retain the type information like I have above.
The reason why I want this is to create test cases. I've got a bunch of say n
functions and m
values. Eventually I will map a function over these which reduces them all to the same type (a Test
) but up to that point there's a bunch of different types for the n*m
testcases I want to perform (it's actually not that simple as some functions can only take restricted subsets of the values).
So naturally it would good to have other functions these heterogeneous lists, like some sort of map
for example.
I've had a look at HList, but it hasn't been updated in the last year and a bit, and I wasn't sure if it was the most appropriate tool anyway.