Is it possible to calculate the list of cubes in a neat way?

Is it possible to simplify the following function with higher order functions, Monads, or what do you have?

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

The function simply creates a list of all triple permutations of the list items. For instance:

 > 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)] 
+4
source share
6 answers

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 to the list using it in the list, the monad gives you combinations for free.

 > sequence $ replicate 3 "01" ["000","001","010","011","100","101","110","111"] 
+8
source

Moving from Bill's answer because this code uses the list monad, we can use the "applicative" style for "with higher order functions." Regardless of whether this is a good idea, it remains as an exercise for the engineer.

 import Control.Applicative cube :: [a] -> [b] -> [c] -> [(a,b,c)] cube xyz = (,,) <$> x <*> y <*> z 
+10
source

In fact, your understanding of the list is to use the List monad.

Another way to write this:

 cube :: [a] -> [(a,a,a)] cube list = do x <- list y <- list z <- list return (x, y, z) 
+7
source

This is actually not a serious answer, but I still have to offer it. Mostly for the sake of madness.

 import Control.Monad import Control.Monad.Instances cube :: [a] -> [(a, a, a)] cube = join . join $ liftM3 (,,) 

Good luck with that.:)

+6
source

To model what Joey Adams did:

 g>replicateM 3 [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]] 

For a complete solution (give it a list and get 3 tuples), you can do something like this:

 g>let cube = map (\(a:b:c:_) -> (a, b, c)) . replicateM 3 cube :: [t] -> [(t, t, t)] (0.00 secs, 526724 bytes) g>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)] it :: [(Integer, Integer, Integer)] 

But IMHO, the decision of Edward Z. Young dominates.

+3
source

Who needs monads if you have a beat?

 import Data.Bits cube :: [(Int,Int,Int)] cube = map tuple [0..7] where tuple x = (1 + div (x .&. 4) 4, 1 + div (x .&. 2) 2, 1 + x .&. 1) 
+2
source

Source: https://habr.com/ru/post/1334394/


All Articles