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
)