let product ?filter f l1 l2 = Counter.(
let c = create () in
let tick = match filter with
| Some p -> fun e1 e2 -> if p e1 e2 then tick c (f e1 e2)
| None -> fun e1 e2 -> tick c (f e1 e2)
in
List.iter ~f:(fun e1 -> List.iter ~f:(tick e1) l2) l1 ;
stream c
)