[Haskell-beginners] generating the set of all finite-valued ...

Jan Jakubuv jakubuv at gmail.com
Fri Apr 24 06:36:44 EDT 2009

On Fri, Apr 24, 2009 at 12:16:06AM +0200, Erik Quaeghebeur wrote:
> Aha. Great. Thanks, Jan. And now I realized that I don't really care 
> about the domain, so I said:
> Prelude> let m = mapM (\x -> [(x,-1),(x,0),(x,1)]) ['a','b','c']
> Prelude> map (\x -> snd $ unzip x) m
> [[-1,-1,-1],[-1,-1,0],[-1,-1,1],[-1,0,-1],[-1,0,0],[-1,0,1],[-1,1,-1],[-1,1,0],[-1,1,1],[0,-1,-1],[0,-1,0],[0,-1,1],[0,0,-1],[0,0,0],[0,0,1],[0,1,-1],[0,1,0],[0,1,1],[1,-1,-1],[1,-1,0],[1,-1,1],[1,0,-1],[1,0,0],[1,0,1],[1,1,-1],[1,1,0],[1,1,1]]
> Any more direct way of doing this? (Still trying to understand how the  
> mapM works... I've found it's sequence.map, but that doesn't really 
> help.)

Well, you can write:

    mapM (const [-1,0,1]) [1..3]

mapM takes a function which returns a computation for a given argument. In
this case the function always returns the computation [-1,0,1] which you can
think of as a non-deterministic computation resulting in either -1, or 0, or
1. This computation is executed for every value in the list [1..3] and
because this list has three values the execution results in [x,y,z] where
each of x, y, and z is either -1, or 0, or -1. This gives you all
variations. You can also write:

    [[x,y,z] | x<-[-1,0,1], y<-[-1,0,1], z<-[-1,0,1]]


Heriot-Watt University is a Scottish charity
registered under charity number SC000278.

More information about the Beginners mailing list