That is quite spectacular. I
revised my knowledge of sequence
with a little function, akin to “sequence
[xs1,xs2]”:
seq2 xs1 xs2 = do x1 <- xs1
x2
<- xs2
return
[x1,x2]
> seq2 [0,1] [0,1,2]
> [[0,0],[0,1],[0,2],[1,0],[1,1],[1,2]]
I like your point-free style too;
and that’s a nice use of pred.
Many thanks,
Paul
The iota function you're looking for can be a whole lot simpler if you
know about monads (list monad in particular) and sequence. For lists,
sequence has the following behaviour:
sequence
[xs1,xs2, ... xsn] =
[[x1,x2, ... , xn] | x1 <- xs1, x2 <- xs2, ... , xn <- xsn]
Using
this, you can reduce your iota function to a powerful one-liner:
iota
= sequence . map (enumFromTo 0 . pred)
Kind
regards,
Raynor
Vliegendhart
From: Paul Keir
Sent: 01 June 2009 10:01
To: haskell-cafe@haskell.org
Subject: iota
Hi all,
I was looking for an APL-style “iota” function
for array indices. I noticed
“range” from Data.Ix which, with a zero for the
lower bound (here (0,0)),
gives the values I need:
> let (a,b) = (2,3)
> index ((0,0),(a-1,b-1))
> [(0,0),(0,1),(0,2),(1,0),(1,1),(1,2)]
However, I need the results as a list of lists rather than a
list of tuples; and
my input is a list of integral values. I ended up writing
the following function
instead. The function isn’t long, but longer than I
first expected. Did I miss a
simpler approach?
iota :: (Integral a) => [a] -> [[a]]
iota is = let count = product is
tups = zip (tail $ scanr (*) 1
is) is
buildRepList (r,i) =
genericTake count $ cycle $
[0..i-1]
>>= genericReplicate r
lists = map buildRepList tups
in transpose lists
> length $ iota [2,3,4]
> 24
Thanks,
Paul