|
From: <sp...@sc...> - 2006-08-29 19:36:57
|
Hi all,
I found myself working with lists containing polymorphic variants, and
I've found the following simple function very useful for improving the
readability of my code (examples are in revised syntax since I've
forgotten the "old" syntax):
value map_reduce op zero map_f list =
(List.fold_left op zero (List.filter_map map_f list));
This may of course be defined slightly more efficiently as
value map_reduce op zero map_f list =
(List.fold_left
(fun acc av ->
(match map_f av with
[ Some x -> op acc x
| None -> acc ]))
zero
list);
which avoids the creation of a temporary list.
Here's an example of usage: Let's say I have a polymorphic variant
type t = [= `A of int | `B of bool | `C of int ]
and I have a list containing values of type t, say
lst = [ `A 5 ; `A 2 ; `B false ; `B true ; `C 3 ]
and I want to extract and combine the values of the different variant
values in different ways. Using both fold_left and filter_map this looks
like
let a_total = List.fold_left (\+) 0
(List.filter_map (fun [ `A x -> Some x | _ -> None ]) lst);
let c_max = List.fold_left max 0
(List.filter_map (fun [ `A x -> Some x | _ -> None ]) lst);
let b = List.fold_left (\||) False
(List.filter_map (fun [ `B x -> Some x | _ -> None ]) lst);
With map_reduce this becomes
let a_total =
map_reduce (\+) 0 (fun [ `A x -> Some x | _ -> None ]) lst;
let c_max =
map_reduce max 0 (fun [ `A x -> Some x | _ -> None ]) lst;
let b =
map_reduce (\||) False (fun [ `B x -> Some x | _ -> None ]) lst;
which I think is more readable since it removes noise (the extra
parantheses and the "superfluous" call to a second function). If you
want to get rid of the temporary list creations the version without
map_reduce of course gets much, much uglier.
Do you think this should be added to ExtLib.ExtList, or is it too
"specialized"?
--
Bardur Arantsson
<bar...@TH...>
There is no truth, only facts to be manipulated.
S.E. Corff, NSA Collection Manager
|