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 |