From: skaller <skaller@users.sourceforge.net>
To: Jon Harrop <jon@ffconsultancy.com>
Cc: caml-list@yquem.inria.fr
Subject: Re: [Caml-list] to merge list of lists
Date: Tue, 06 Mar 2007 06:02:38 +1100 [thread overview]
Message-ID: <1173121358.25568.104.camel@rosella.wigram> (raw)
In-Reply-To: <200703050853.12223.jon@ffconsultancy.com>
On Mon, 2007-03-05 at 08:53 +0000, Jon Harrop wrote:
> On Monday 05 March 2007 08:37, skaller wrote:
> > On Mon, 2007-03-05 at 17:10 +1100, Pietro Abate wrote:
> > > mergel [] [[1;2;3];[4;5;6];[7;8;9]];;
> > > - : int list list = [[1; 4; 7]; [2; 5; 8]; [3; 6; 9]]
> >
> > In this case there is a library function:
> >
> > List.concat
> >
> > that already does exactly what you want :)
>
> List.concat doesn't do that:
>
> # List.concat [[1;2;3];[4;5;6];[7;8;9]];;
> - : int list = [1; 2; 3; 4; 5; 6; 7; 8; 9]
>
> Note that the OP is not asking for a concat or even a merge, but a transpose.
Yes, sorry! I didn't look closely enough.
I have a related function in Felix, which transposes
a tuple of tuples, which is done with a term like
_tuple_trans ((1,2,3),(4,5,6),(7,8,9))
here's the code, which is quite imperative, and which has
extra mess from the error diagnostics. In this case there
is a special representation for the type of a tuple
with all the elements the same type, instead of
int * int * int
the type can be given as
int * 3
where 3 = 1 + 1 + 1, 1 is the usual unit type, and + is
an anonymous variant combinator. A type like 3 is
called a unitsum (it is a sum of units). This in turn
allows arrays to be considered as tuples of the same
element type, and the special representation is required
to allow arrays of large extent (there's no way a representation
of a 20,000 integer tuple is going to fly in a production
compiler). Also note the result of this calculation is
a bound term, the function 'be' binds expressions,
and this code is part of that function.
So the code is somewhat more complex, but it does the
same thing. It's very hard to tell if the code is correct:
I'd be interested in a more functional way to do this
that was actually simpler (but had the same semantics).
The 'guts' of the calculation is done by the 'tr'
function introduced on line 2.
| `AST_apply (sr,(`AST_name (_,"_tuple_trans",[]),e)) ->
let tr nrows ncolumns =
let e' = ref [] in
for i = nrows - 1 downto 0 do
let x = ref [] in
for j = ncolumns - 1 downto 0 do
let v = `AST_get_n (sr,(i,`AST_get_n (sr,(j,e)))) in
x := v :: !x;
done;
e' := `AST_tuple (sr,!x) :: (!e');
done
;
be (`AST_tuple (sr,!e'))
in
let calnrows t =
let nrows =
match t with
| `BTYP_tuple ls -> length ls
| `BTYP_array (_,`BTYP_unitsum n) -> n
| _ -> clierrn [sr] "Tuple transpose requires entry to be tuple"
in
if nrows < 2 then
clierr sr "Tuple transpose requires tuple argument with 2 or
more elements"
;
nrows
in
let colchk nrows t =
match t with
| `BTYP_tuple ls ->
if length ls != nrows then
clierr sr ("Tuple transpose requires entry to be tuple of
length " ^ si nrows)
| `BTYP_array (_,`BTYP_unitsum n) ->
if n != nrows then
clierr sr ("Tuple transpose requires entry to be tuple of
length " ^ si nrows)
| _ -> clierr sr "Tuple transpose requires entry to be tuple"
in
let _,t = be e in
let ncolumns, nrows =
match t with
| `BTYP_tuple ls ->
let ncolumns = length ls in
let nrows = calnrows (hd ls) in
iter (colchk nrows) ls;
ncolumns, nrows
| `BTYP_array (t,`BTYP_unitsum ncolumns) ->
let nrows = calnrows t in
ncolumns, nrows
| _ -> clierr sr "Tuple transpose requires tuple argument"
in
if nrows > 20 then
clierr sr ("tuple fold: row bound " ^ si nrows ^ ">20, to
large")
;
if ncolumns> 20 then
clierr sr ("tuple fold: column bound " ^ si ncolumns^ ">20, to
large")
;
tr nrows ncolumns
--
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net
next prev parent reply other threads:[~2007-03-05 19:02 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-03-05 6:10 Pietro Abate
2007-03-05 8:37 ` [Caml-list] " skaller
2007-03-05 8:53 ` Jon Harrop
2007-03-05 19:02 ` skaller [this message]
2007-03-05 19:40 ` skaller
2007-03-07 14:33 ` Roland Zumkeller
2007-03-05 9:47 ` Zheng Li
2007-03-05 14:42 ` Zheng Li
2007-03-06 0:07 ` [Caml-list] " Pal-Kristian Engstad
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1173121358.25568.104.camel@rosella.wigram \
--to=skaller@users.sourceforge.net \
--cc=caml-list@yquem.inria.fr \
--cc=jon@ffconsultancy.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox