Envoyé par
gasche
Je n'ai pas compris ce que tu veux, à part la fin "chaîne de responsabilité".
Du coup j'ai écrit un peu de code pour faire un truc qui ressemble, mais je ne sais pas si ça correspond à ce que tu demandes, vu que je n'ai pas bien compris ce que tu voulais.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| type ('a, 'b) decision =
| PassNext of 'a
| Return of 'b
let rec eval handlers arg = match handlers with
| [] -> failwith "no handlers"
| h::rest ->
match h arg with
| Return ret -> ret
| PassNext new_arg -> eval rest new_arg
let filter cond handler = fun arg ->
if cond arg then handler arg else PassNext arg
let passnext f = fun arg -> PassNext (f arg)
let return f = fun arg -> Return (f arg)
let watcher name = fun arg ->
Printf.printf "%s: saw %d\n" name arg;
PassNext arg
let () =
let handlers = [
watcher "h1";
filter (fun n -> n mod 2 = 0) (watcher "h2");
filter (fun n -> n > 10) (return ((+) 2));
passnext ((+) 1);
watcher "h3";
return (fun _ -> 0);
] in
let test arg =
print_endline "eval...";
let result = eval handlers arg in
Printf.printf "result: %d\n\n" result in
test 3;
test 4;
test 21 |
je ne comprend pas trop à quoi servent passnext et return
EDIT : ah ok return stoppe l'évaluation et passnext passe au suivant
bon ça correspond à ce que je demandais, une liste de handlers-conditions qui catchent ou non un argument (chaine de responsabilité)
par contre est-ce qu'il possible de filtrer selon le type de l'argument ?
par ex si j'ai :
type event = EventA |EventB
et que je veux :
1 2
| filter (fun event -> event of EventA) (watcher "EventA");
filter (fun event -> event of EventB) (watcher "EventB"); |
comment m'y prendre ?
niveau performances, c'est plus lent qu'un pattern matching classique ?
Partager