15 for operators that have side-effects or raise exceptions! |
15 for operators that have side-effects or raise exceptions! |
16 *) |
16 *) |
17 |
17 |
18 signature PAR_LIST = |
18 signature PAR_LIST = |
19 sig |
19 sig |
20 val release_results: 'a Exn.result list -> 'a list |
|
21 val map: ('a -> 'b) -> 'a list -> 'b list |
20 val map: ('a -> 'b) -> 'a list -> 'b list |
22 val get_some: ('a -> 'b option) -> 'a list -> 'b option |
21 val get_some: ('a -> 'b option) -> 'a list -> 'b option |
23 val find_some: ('a -> bool) -> 'a list -> 'a option |
22 val find_some: ('a -> bool) -> 'a list -> 'a option |
24 val exists: ('a -> bool) -> 'a list -> bool |
23 val exists: ('a -> bool) -> 'a list -> bool |
25 val forall: ('a -> bool) -> 'a list -> bool |
24 val forall: ('a -> bool) -> 'a list -> bool |
26 end; |
25 end; |
27 |
26 |
28 structure ParList: PAR_LIST = |
27 structure ParList: PAR_LIST = |
29 struct |
28 struct |
30 |
29 |
31 (* release results *) |
|
32 |
|
33 fun proper_exn (Exn.Result _) = NONE |
|
34 | proper_exn (Exn.Exn Interrupt) = NONE |
|
35 | proper_exn (Exn.Exn exn) = SOME exn; |
|
36 |
|
37 fun release_results results = |
|
38 (case get_first proper_exn results of |
|
39 SOME exn => raise exn |
|
40 | NONE => List.map Exn.release results); |
|
41 |
|
42 |
|
43 (* map *) |
|
44 |
|
45 fun raw_map f xs = |
30 fun raw_map f xs = |
46 let val group = TaskQueue.new_group () in |
31 let val group = TaskQueue.new_group () in |
47 Future.join_results (List.map (fn x => Future.future (SOME group) [] true (fn () => f x)) xs) |
32 Future.join_results (List.map (fn x => Future.future (SOME group) [] true (fn () => f x)) xs) |
48 end; |
33 end; |
49 |
34 |
50 fun map f xs = release_results (raw_map f xs); |
35 fun map f xs = Future.release_results (raw_map f xs); |
51 |
|
52 |
|
53 (* get_some etc. *) |
|
54 |
36 |
55 fun get_some f xs = |
37 fun get_some f xs = |
56 let |
38 let |
57 exception FOUND of 'b option; |
39 exception FOUND of 'b option; |
58 fun found (Exn.Exn (FOUND some)) = some |
40 fun found (Exn.Exn (FOUND some)) = some |
59 | found _ = NONE; |
41 | found _ = NONE; |
60 val results = raw_map (fn x => (case f x of NONE => () | some => raise FOUND some)) xs; |
42 val results = raw_map (fn x => (case f x of NONE => () | some => raise FOUND some)) xs; |
61 in |
43 in |
62 (case get_first found results of |
44 (case get_first found results of |
63 SOME y => SOME y |
45 SOME y => SOME y |
64 | NONE => |
46 | NONE => (Future.release_results results; NONE)) |
65 (case get_first proper_exn results of |
|
66 SOME exn => raise exn |
|
67 | NONE => |
|
68 (case get_first Exn.get_exn results of |
|
69 SOME exn => raise exn |
|
70 | NONE => NONE))) |
|
71 end; |
47 end; |
72 |
48 |
73 fun find_some P = get_some (fn x => if P x then SOME x else NONE); |
49 fun find_some P = get_some (fn x => if P x then SOME x else NONE); |
74 |
50 |
75 fun exists P = is_some o get_some (fn x => if P x then SOME () else NONE); |
51 fun exists P = is_some o get_some (fn x => if P x then SOME () else NONE); |