Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I compute the cube list in a neat way?

Can the following function be simplified with higher order functions, Monads or what have you?

cube list = [(x, y, z) | x <- list, y <- list, z <- list]

The function simply creates a list of all triple-permutations of the elements of the list. For example:

> cube [1..2]
[(1,1,1),(1,1,2),(1,2,1),(1,2,2),(2,1,1),(2,1,2),(2,2,1),(2,2,2)]
like image 992
fredoverflow Avatar asked Nov 28 '22 01:11

fredoverflow


2 Answers

Going from Bill's answer, because this is code uses the list monad, we can use "applicative" style to do "with higher-order functions". Whether or not this is a good idea is left as an exercise for the engineer.

import Control.Applicative

cube :: [a] -> [b] -> [c] -> [(a,b,c)]
cube x y z = (,,) <$> x <*> y <*> z
like image 60
Edward Z. Yang Avatar answered Dec 04 '22 02:12

Edward Z. Yang


Although it gives you lists instead of tuples, you can use the sequence function in Control.Monad:

> let list = [1..2]
> sequence [list, list, list]
[[1,1,1],[1,1,2],[1,2,1],[1,2,2],[2,1,1],[2,1,2],[2,2,1],[2,2,2]]

The sequence function is neat because, although its "intended" purpose is to take a list of actions, do them in order, and return their results in a list, using it on the list monad gives you combinations for free.

> sequence $ replicate 3 "01"
["000","001","010","011","100","101","110","111"]
like image 42
Joey Adams Avatar answered Dec 04 '22 02:12

Joey Adams