Closed rlefevre closed 6 years ago
Hey this looks pretty good to me.
I find the name cartesianProduct
a lot nicer. cartesianProduct
suggest to me exactly what you implemented, while sequence
doesnt suggest much of anything. That could just be reflecting my unique experience.
I think you're right. The sequence
name does not make much sense in a context limited to lists. I renamed it to cartesianProduct
and made a few syntactic improvements (hopefully).
Hmm, maybe one issue is that cartesianProduct [[]] == []
but cartesianProduct [] == [[]]
.
This seems wrong.
@rlefevre, mathematically this is exactly correct. What one should expect of a Cartesian product of several lists is something like length (cartesianProduct lists) == product (map length lists)
where product = foldr (*) 1
.
The two examples you give do satisfy this property. If you changed those cases, e.g., swapping their results, the property would not anymore hold.
Ah, thank you very much. I had a doubt about cartesianProduct [] == [[]]
because . I should have reviewed my maths about the nullary cartesian product sequence [] == []
in haskell
In any category, the product of an empty family is a terminal object of that category [...] and the terminal object is a singleton set.
This was the occasion to add a test. Thanks again.
I don’t think it is true that in Haskell, the sequence function on the empty list gives the empty list. It certainly gives „return []“, which in the case of the list monad is exactly [[]].
You're right again, I was tricked by the list monad and ghci
that produces (as expected) the same output for []
and return []
. Thank you for the clarification.
Hi,
I needed this for a project, and this is quite useful, so I thought I might as well do a pull request, in case you think it has its place in
List.Extra
.I kept the name
sequence
because it is typically named like this for monads (like incore/Task
) but in the list context, maybecartesian
orcartesianProduct
might be better.The implementation is almost identical to
sequence
incore/Task
(but usinglift2
instead ofmap2
to explore all combinations).