Haskell: Cartesian product [duplicate]
Possible Duplicate:
Cartesian product
I'm Haskell newbie and I have a problem. I want to do some function that will take first element of list and conn开发者_开发百科ect to all elements of second list, after that take second element from first list and do the same. For example I want to take: [[1],[2],[3]) and [[4],[5],[6]] and get in output
[([1],[4]),([1],[5]),([1],[6]),
([2],[4]),([2],[5]),([2],[6]),
([3],[4]),([3],[5]),([3],[6])]
The closes one I found is transpose
transpose [[1,2,3],[4,5,6]]
[[1,4],[2,5],[3,6]]
I would appreciate any help.
Edit: Shame on me. I found solution
[[x,y] | x <- [[1],[2],[3]], y <- [[4],[5],[6]]]
Which result is:
[[[1],[4]],[[1],[5]],[[1],[6]],[[2],[4]],[[2],[5]],[[2],[6]],[[3],[4]],[[3],[5]],[[3],[6]]]
import Control.Applicative
(,) <$> [[1],[2],[3]] <*> [[4],[5],[6]]
--[([1],[4]),([1],[5]),([1],[6]),([2],[4]),([2],[5]),([2],[6]),([3],[4]),([3],[5]),([3],[6])]
See http://learnyouahaskell.com/functors-applicative-functors-and-monoids#applicative-functors for an explanation.
You can also use do-Notation, as lists are not only Applicative
, but Monads
, too:
do x<-[[1],[2],[3]]; y<-[[4],[5],[6]]; return (x,y)
--[([1],[4]),([1],[5]),([1],[6]),([2],[4]),([2],[5]),([2],[6]),([3],[4]),([3],[5]),([3],[6])]
I'm also new to haskell, here is my solution to your question, hope it's helpful:
f [] _ = []
f (x:xs) ys = zip (take (length ys) (repeat x)) ys ++ f xs ys
I think the code explains itself quite straight forward :)
This is interesting.
sequence [[[1],[2],[3]] , [[4],[5],[6]]]
精彩评论