Module OLinq

module OLinq: sig .. end

LINQ-like operations on collections

The purpose is to provide powerful combinators to express iteration, transformation and combination of collections of items.

Functions and operations are assumed to be referentially transparent, i.e. they should not rely on external side effects, they should not rely on the order of execution.

      OLinq.(
        of_list [1;2;3]
        |> flat_map (fun x -> (x -- (x+10)))
        |> count ()
        |> flat_map of_pmap
        |> sort ()
        |> run_list
      );;

      - : (int * int) list = [(1, 1); (2, 2); (3, 3); (4, 3); (5, 3); (6, 3);
                              (7, 3); (8, 3); (9, 3); (10, 3); (11, 3); (12, 2); (13, 1)]

        OLinq.(
          IO.read_file "/tmp/foo"
          |> IO.lines
          |> sort ()
          |> IO.to_file_lines "/tmp/bar"
        );;
      - :  `Ok ()
    

      OLinq.(
        1 -- 20
        |> group_by (fun x -> x mod 3)
        |> run_list
      ) ;;
      - : (int * int list) list =
      [(2, [20; 17; 14; 11; 8; 5; 2]);
       (0, [18; 15; 12; 9; 6; 3; 0]);
       (1, [19; 16; 13; 10; 7; 4; 1])]
    


type 'a sequence = ('a -> unit) -> unit 
type 'a equal = 'a -> 'a -> bool 
type 'a ord = 'a -> 'a -> int 
type 'a hash = 'a -> int 
type 'a or_error = [ `Error of string | `Ok of 'a ] 
type 'a printer = Format.formatter -> 'a -> unit 
module Iterable: sig .. end

Polymorphic Maps


type ('a, 'b) map = ('a, 'b) OLinq_map.t 

Main Type


type ('a, +[< `Any | `AtMostOne | `One ]) t 
Type of a query that returns zero, one or more values of type 'a. The parameter 'card indicates how many elements are in the collection, with `Any indicating the number is unknown, `AtMostOne that there are 0 or 1 elements and `One exactly one.

Conceptually, the cardinalities are ordered from most precise (`One) to least precise (`Any): `One < `AtMostOne < `Any.

type 'a t_any = ('a, [ `Any ]) t 
type 'a t_one = ('a, [ `One ]) t 
type 'a t_at_most_one = ('a, [ `AtMostOne ]) t 

Initial values


val empty : ('a, [< `Any | `AtMostOne | `One > `AtMostOne ]) t
Empty collection
val return : 'a -> ('a, [< `Any | `AtMostOne | `One > `One ]) t
Return one value
val of_list : 'a list -> ('a, [ `Any ]) t
Query that just returns the elements of the list
val of_array : 'a array -> ('a, [ `Any ]) t
val of_array_i : 'a array -> (int * 'a, [ `Any ]) t
val range : int -> int -> (int, [ `Any ]) t
range i j goes from i up to j included
val (--) : int -> int -> (int, [ `Any ]) t
Synonym to OLinq.range
val of_hashtbl : ('a, 'b) Hashtbl.t -> ('a * 'b, [ `Any ]) t
val of_seq : 'a sequence -> ('a, [ `Any ]) t
Query that returns the elements of the given sequence.
val of_vec : 'a OLinq_vec.t -> ('a, [ `Any ]) t
val of_queue : 'a Queue.t -> ('a, [ `Any ]) t
val of_stack : 'a Stack.t -> ('a, [ `Any ]) t
val of_string : string -> (char, [ `Any ]) t
Traverse the characters of the string
val of_map : ('a, 'b) map -> ('a * 'b, [ `Any ]) t
of_map m yields each binding of m
val of_multimap : ('a, 'b list) map -> ('a * 'b, [ `Any ]) t
of_multimap m yields each single binding of m

Execution

val run : ?limit:int ->
('a, [< `Any | `AtMostOne | `One ]) t -> 'a Iterable.t
Execute the query, possibly returning an error if things go wrong
limit : max number of values to return
val run_list : ?limit:int -> ('a, [< `Any | `AtMostOne | `One ]) t -> 'a list
val run_array : ?limit:int -> ('a, [< `Any | `AtMostOne | `One ]) t -> 'a array
val run_vec : ?limit:int -> ('a, [< `Any | `AtMostOne | `One ]) t -> 'a OLinq_vec.t
val run1 : ('a, [ `One ]) t -> 'a
Run the query and return the only value
val run_head : ('a, [< `Any | `AtMostOne | `One ]) t -> 'a option
Return first result
val run1_exn : ('a, [< `Any | `AtMostOne | `One ]) t -> 'a
unsafe shortcut for OLinq.run_head.
Raises Not_found if the query contains 0 element

Basics

val map : ('a -> 'b) ->
('a, [< `Any | `AtMostOne | `One ] as 'c) t -> ('b, 'c) t
Map each value
val (>|=) : ('a, [< `Any | `AtMostOne | `One ] as 'c) t ->
('a -> 'b) -> ('b, 'c) t
Infix synonym of OLinq.map
val filter : ('a -> bool) ->
('a, [< `Any | `AtMostOne | `One ]) t -> ('a, [ `Any ]) t
Filter out values that do not satisfy predicate. We lose precision on the cardinality because of type system constraints.
val size : ('a, [< `Any | `AtMostOne | `One ]) t ->
(int, [< `Any | `AtMostOne | `One > `One ]) t
size t returns one value, the number of items returned by t
val choose : ('a, [< `Any | `AtMostOne | `One ]) t ->
('a, [< `Any | `AtMostOne | `One > `AtMostOne ]) t
Choose one element (if any, otherwise empty) in the collection. This is like a "cut" in prolog.
val filter_map : ('a -> 'b option) ->
('a, [< `Any | `AtMostOne | `One ]) t -> ('b, [ `Any ]) t
Filter and map elements at once
val flat_map_seq : ('a -> 'b sequence) ->
('a, [< `Any | `AtMostOne | `One ]) t -> ('b, [ `Any ]) t
Same as OLinq.flat_map but using sequences
val flat_map_l : ('a -> 'b list) ->
('a, [< `Any | `AtMostOne | `One ]) t -> ('b, [ `Any ]) t
map each element to a collection and flatten the result
val flatten_list : ('a list, [< `Any | `AtMostOne | `One ]) t -> ('a, [ `Any ]) t
val flatten_seq : ('a sequence, [< `Any | `AtMostOne | `One ]) t ->
('a, [ `Any ]) t
val flatten_map : (('a, 'b) map, [< `Any | `AtMostOne | `One ]) t ->
('a * 'b, [ `Any ]) t
val flatten_multimap : (('a, 'b list) map, [< `Any | `AtMostOne | `One ]) t ->
('a * 'b, [ `Any ]) t
val take : int -> ('a, [< `Any | `AtMostOne | `One ]) t -> ('a, [ `Any ]) t
Take at most n elements
val take1 : ('a, [< `Any | `AtMostOne | `One ]) t ->
('a, [< `Any | `AtMostOne | `One > `AtMostOne ]) t
Specialized version of OLinq.take that keeps only the first element
val take_while : ('a -> bool) ->
('a, [< `Any | `AtMostOne | `One ]) t -> ('a, [ `Any ]) t
Take elements while they satisfy a predicate
val sort : ?cmp:'a ord -> unit -> ('a, [ `Any ]) t -> ('a, [ `Any ]) t
Sort items by the given comparison function. Only meaningful when there are potentially many elements
val sort_by : ?cmp:'b ord ->
('a -> 'b) -> ('a, [ `Any ]) t -> ('a, [ `Any ]) t
sort_by proj c sorts the collection c by projecting elements using proj, then using cmp to order them
val distinct : ?cmp:'a ord -> unit -> ('a, [ `Any ]) t -> ('a, [ `Any ]) t
Remove duplicate elements from the input collection. All elements in the result are distinct.

Aggregation

val group_by : ?cmp:'b ord ->
?eq:'b equal ->
?hash:'b hash ->
('a -> 'b) -> ('a, [ `Any ]) t -> ('b * 'a list, [ `Any ]) t
group_by f takes a collection c as input, and returns a collection of pairs k, l where every element x of l satifies f x = k. In other words, elements of the collection that have the same image by f are grouped in the same list.
val group_by_reflect : ?cmp:'b ord ->
?eq:'b equal ->
?hash:'b hash ->
('a -> 'b) ->
('a, [ `Any ]) t ->
(('b, 'a list) map, [< `Any | `AtMostOne | `One > `One ]) t
group_by_reflect f takes a collection c as input, and returns a multimap m such that for each x in c, x occurs in m under the key f x. In other words, f is used to obtain a key from x, and x is added to the multimap using this key.
val count : ?cmp:'a ord ->
?eq:'a equal ->
?hash:'a hash ->
unit -> ('a, [ `Any ]) t -> ('a * int, [ `Any ]) t
count c counts how many times each element of the collection occur, and returns pairs of x, count(x)
val count_reflect : ?cmp:'a ord ->
?eq:'a equal ->
?hash:'a hash ->
unit ->
('a, [ `Any ]) t ->
(('a, int) map, [< `Any | `AtMostOne | `One > `One ]) t
count_reflect c returns a map from elements of c to the number of time those elements occur.
val fold : ('b -> 'a -> 'b) ->
'b ->
('a, [< `Any | `AtMostOne | `One ]) t ->
('b, [< `Any | `AtMostOne | `One > `One ]) t
Fold over the collection
val is_empty : ('a, [< `Any | `AtMostOne ]) t ->
(bool, [< `Any | `AtMostOne | `One > `One ]) t
val sum : (int, [< `Any | `AtMostOne ]) t ->
(int, [< `Any | `AtMostOne | `One > `One ]) t
val contains : ?eq:'a equal ->
'a ->
('a, [< `Any | `AtMostOne | `One ]) t ->
(bool, [< `Any | `AtMostOne | `One > `One ]) t
contains x q returns true if x is among the elements returned by q. Careful, this runs q and might be slow!
val average : (int, [< `Any | `AtMostOne | `One ]) t ->
(int, [< `Any | `AtMostOne | `One > `One ]) t
val max : (int, [< `Any | `AtMostOne | `One ]) t ->
(int, [< `Any | `AtMostOne | `One > `One ]) t
val min : (int, [< `Any | `AtMostOne | `One ]) t ->
(int, [< `Any | `AtMostOne | `One > `One ]) t
val for_all : ('a -> bool) ->
('a, [< `Any | `AtMostOne | `One ]) t ->
(bool, [< `Any | `AtMostOne | `One > `One ]) t
val exists : ('a -> bool) ->
('a, [< `Any | `AtMostOne | `One ]) t ->
(bool, [< `Any | `AtMostOne | `One > `One ]) t
val find : ('a -> bool) ->
('a, [< `Any | `AtMostOne | `One ]) t ->
('a option, [< `Any | `AtMostOne | `One > `One ]) t
val find_map : ('a -> 'b option) ->
('a, [< `Any | `AtMostOne | `One ]) t ->
('b option, [< `Any | `AtMostOne | `One > `One ]) t

Binary Operators

val join : ?cmp:'key ord ->
?eq:'key equal ->
?hash:'key hash ->
('a -> 'key) ->
('b -> 'key) ->
merge:('key -> 'a -> 'b -> 'c option) ->
('a, [< `Any | `AtMostOne | `One ]) t ->
('b, [< `Any | `AtMostOne | `One ]) t -> ('c, [ `Any ]) t
join key1 key2 ~merge is a binary operation that takes two collections a and b, projects their elements resp. with key1 and key2, and combine values (x,y) from (a,b) with the same key using merge. If merge returns None, the combination of values is discarded.
val outer_join : ?cmp:'key ord ->
?eq:'key equal ->
?hash:'key hash ->
('a -> 'key) ->
('b -> 'key) ->
merge:('key -> 'a list -> 'b list -> 'c option) ->
('a, [< `Any | `AtMostOne | `One ]) t ->
('b, [< `Any | `AtMostOne | `One ]) t -> ('c, [ `Any ]) t
outer_join key1 key2 ~merge is a binary operation that takes two collections a and b, projects their elements resp. with key1 and key2, and, for each key k occurring in at least one of them:
Since 0.2
val group_join : ?cmp:'a ord ->
?eq:'a equal ->
?hash:'a hash ->
('b -> 'a) ->
('a, [< `Any | `AtMostOne | `One ]) t ->
('b, [< `Any | `AtMostOne | `One ]) t ->
('a * 'b list, [ `Any ]) t
group_join key2 associates to every element x of the first collection, all the elements y of the second collection such that eq x (key y). Elements of the first collections without corresponding values in the second one are mapped to []
val group_join_reflect : ?cmp:'a ord ->
?eq:'a equal ->
?hash:'a hash ->
('b -> 'a) ->
('a, [< `Any | `AtMostOne | `One ]) t ->
('b, [< `Any | `AtMostOne | `One ]) t ->
(('a, 'b list) map, [< `Any | `AtMostOne | `One > `One ]) t
Same as OLinq.group_join, but reflects the groups as a multimap
val product : ('a, [< `Any | `AtMostOne | `One ]) t ->
('b, [< `Any | `AtMostOne | `One ]) t -> ('a * 'b, [ `Any ]) t
Cartesian product
val append : ('a, [< `Any | `AtMostOne | `One ]) t ->
('a, [< `Any | `AtMostOne | `One ]) t -> ('a, [ `Any ]) t
Append two collections together
val inter : ?cmp:'a ord ->
?eq:'a equal ->
?hash:'a hash ->
('a, [< `Any | `AtMostOne | `One ]) t ->
('a, [< `Any | `AtMostOne | `One ]) t -> ('a, [ `Any ]) t
Intersection of two collections. Each element will occur at most once in the result
val union : ?cmp:'a ord ->
?eq:'a equal ->
?hash:'a hash ->
('a, [< `Any | `AtMostOne | `One ]) t ->
('a, [< `Any | `AtMostOne | `One ]) t -> ('a, [ `Any ]) t
Union of two collections. Each element will occur at most once in the result
val diff : ?cmp:'a ord ->
?eq:'a equal ->
?hash:'a hash ->
('a, [< `Any | `AtMostOne | `One ]) t ->
('a, [< `Any | `AtMostOne | `One ]) t -> ('a, [ `Any ]) t
Set difference
val subset : ?cmp:'a ord ->
?eq:'a equal ->
?hash:'a hash ->
('a, [< `Any | `AtMostOne | `One ]) t ->
('a, [< `Any | `AtMostOne | `One ]) t -> (bool, [ `One ]) t
subset () a b returns true if all elements of a belong to b

Tuple and Options


Tuple and Options


Specialized projection operators
val map_fst : ('a -> 'b) ->
('a * 'c, [< `Any | `AtMostOne | `One ] as 'd) t ->
('b * 'c, 'd) t
val map_snd : ('a -> 'b) ->
('c * 'a, [< `Any | `AtMostOne | `One ] as 'd) t ->
('c * 'b, 'd) t
val flatten_opt : ('a option, [< `Any | `AtMostOne | `One ]) t -> ('a, [ `Any ]) t
Flatten the collection by removing None and mapping Some x to x.

Applicative

val pure : 'a -> ('a, [< `Any | `AtMostOne | `One ]) t
Synonym to OLinq.return
val app : ('a -> 'b, [< `Any | `AtMostOne | `One ] as 'c) t ->
('a, 'c) t -> ('b, 'c) t
Apply each function to each value. The cardinality should be the lowest upper bound of both input cardinalities (any,_) -> any, (one,one) -> one, etc.
val (<*>) : ('a -> 'b, [< `Any | `AtMostOne | `One ] as 'c) t ->
('a, 'c) t -> ('b, 'c) t
Infix synonym to OLinq.app

Monad

Careful, those operators do not allow any optimization before running the query, they might therefore be pretty slow.

val flat_map : ('a -> ('b, [< `Any | `AtMostOne | `One ]) t) ->
('a, [< `Any | `AtMostOne | `One ]) t -> ('b, [ `Any ]) t
Use the result of a query to build another query and immediately run it.
val (>>=) : ('a, [< `Any | `AtMostOne | `One ]) t ->
('a -> ('b, [< `Any | `AtMostOne | `One ]) t) -> ('b, [ `Any ]) t
Infix version of OLinq.flat_map

Misc

val lazy_ : ('a lazy_t, [< `Any | `AtMostOne | `One ] as 'b) t -> ('a, 'b) t
exception UnwrapNone
val opt_unwrap_exn : ('a option, [< `Any | `AtMostOne | `One ] as 'b) t -> ('a, 'b) t
Raises UnwrapNone if some option is None

Infix

module Infix: sig .. end

Adapters

val reflect_vec : ('a, [< `Any | `AtMostOne | `One ]) t ->
('a OLinq_vec.t, [< `Any | `AtMostOne | `One > `One ]) t
reflect_seq q evaluates all values in q and returns a sequence of all those values. Also blocks optimizations
val reflect_list : ('a, [< `Any | `AtMostOne | `One ]) t ->
('a list, [< `Any | `AtMostOne | `One > `One ]) t
reflect_list q evaluates all values in q and returns a list of all those values. Also blocks optimizations
val reflect_hashtbl : ('a * 'b, [< `Any | `AtMostOne | `One ]) t ->
(('a, 'b) Hashtbl.t, [< `Any | `AtMostOne | `One > `One ]) t
Build a hashtable from the collection
val reflect_queue : ('a, [< `Any | `AtMostOne | `One ]) t ->
('a Queue.t, [< `Any | `AtMostOne | `One > `One ]) t
val reflect_stack : ('a, [< `Any | `AtMostOne | `One ]) t ->
('a Stack.t, [< `Any | `AtMostOne | `One > `One ]) t
module AdaptSet: 
functor (S : Set.S) -> sig .. end
module AdaptMap: 
functor (M : Map.S) -> sig .. end
module IO: sig .. end
val print : ?sep:string ->
'a printer -> ('a, [< `Any | `AtMostOne | `One ]) t printer
Evaluate the sequence of elements and print them
Since 0.2