(×) :: [a] -> [b] -> [(a,b)] -- Read as: the × operator takes a list of elements of -- type `a` and a list of type `b`, and gives back a -- list of tuples of one `a` and one `b` element xs × ys = [(x,y) | x<-xs, y<-ys] (⊗) :: [[a]] -> [[a]] -> [[a]] xs ⊗ ys = [x++y | x<-xs, y<-ys] main :: IO () main = do print $ [1,2,3] × "pqr" print $ ([1,2] × "pq") × "MN" print $ [1,2] × ("pq" × "MN") print $ ["1","2","3"] ⊗ ["p","q","r"] print $ (["1","2"] ⊗ ["p","q"]) ⊗ ["M","N"] print $ ["1","2"] ⊗ (["p","q"] ⊗ ["M","N"]) print $ map pure [1,2,3] ⊗ map pure [5,6,7]