<commit_before>open Lazy

(* Nondeterminism Monad *)

type 'a stream =
    Nil
  | Cons of 'a * ('a stream) lazy_t

type 'a nondet = 'a stream lazy_t

let mempty = lazy Nil

let ret a = lazy (Cons (a, mempty))

let guard pred =
  if pred then ret () else mempty

(* Combine results returned by a with results
   returned by b. Results from a and b are
   interleaved. *)
let rec mplus a b = from_fun (fun () ->
  match force a with
  | Cons (a1, a2) -> Cons (a1, mplus b a2)
  | Nil           ->
    begin match force b with
    | Nil           -> Nil
    | Cons (b1, b2) -> Cons (b1, mplus a b2)
    end)

let rec bind m f = from_fun (fun () ->
  match force m with
  | Nil         -> Nil
  | Cons (a, b) -> force (mplus (f a) (bind b f)))

(* Execute and get first n results as list,
   use n = -1 to get all values. *)
let run n m =
  let rec go n m acc =
    if n = 0 then List.rev acc
    else
      match force m with
      | Nil         -> List.rev acc
      | Cons (a, b) -> go (pred n) b (a::acc)
  in go n m []

(* Apply function f to the first n values,
   use n = -1 to apply f to all values. *)
let iter n m f =
  let rec go n m =
    if n = 0 then ()
    else
      match force m with
      | Nil         -> ()<commit_msg>optimize "mplus nil b = b"<commit_after>open Lazy

(* Nondeterminism Monad *)

type 'a stream =
    Nil
  | Cons of 'a * ('a stream) lazy_t

type 'a nondet = 'a stream lazy_t

let mempty = lazy Nil

let ret a = lazy (Cons (a, mempty))

let guard pred =
  if pred then ret () else mempty

(* Combine results returned by [a] with results
   returned by [b]. Results from [a] and [b] are
   interleaved. *)
let rec mplus a b = from_fun (fun () ->
  match force a with
  | Cons (a1, a2) -> Cons (a1, mplus b a2)
  | Nil           -> force b)

let rec bind m f = from_fun (fun () ->
  match force m with
  | Nil         -> Nil
  | Cons (a, b) -> force (mplus (f a) (bind b f)))

(* Execute and get first [n] results as list,
   use [n = -1] to get all values. *)
let run n m =
  let rec go n m acc =
    if n = 0 then List.rev acc
    else
      match force m with
      | Nil         -> List.rev acc
      | Cons (a, b) -> go (pred n) b (a::acc)
  in go n m []

(* Apply function [f] to the first n values,
   use [n = -1] to apply [f] to all values. *)
let iter n m f =
  let rec go n m =
    if n = 0 then ()
    else
      match force m with
      | Nil         -> ()
{'fraction_non_alphanumeric': 0.11615320566194838, 'fraction_numerical': 0.00832639467110741, 'mean_word_length': 1.952088452088452, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3697619', 'n_tokens_mistral': 887, 'n_tokens_neox': 868, 'n_words': 398}