Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 119 additions & 0 deletions src/FSharpx.Collections/PersistentVector.fs
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,112 @@ module PersistentVector =
| Some v' -> tryNth j v'
| None -> None

let choose (f: 'T -> 'T1 option) (vector: PersistentVector<'T>) : PersistentVector<'T1> =
let mutable ret = TransientVector()

for item in vector do
match f item with
| Some v -> ret <- ret.conj v
| None -> ()

ret.persistent()

let exists (f: 'T -> bool) (vector: PersistentVector<'T>) =
let mutable found = false
let mutable i = 0

while not found && i < vector.Length do
if f vector.[i] then
found <- true

i <- i + 1

found

let filter (f: 'T -> bool) (vector: PersistentVector<'T>) : PersistentVector<'T> =
let mutable ret = TransientVector()

for item in vector do
if f item then
ret <- ret.conj item

ret.persistent()

let findIndex (f: 'T -> bool) (vector: PersistentVector<'T>) =
let mutable result = -1
let mutable i = 0

while result = -1 && i < vector.Length do
if f vector.[i] then
result <- i

i <- i + 1

if result = -1 then
raise(System.Collections.Generic.KeyNotFoundException("An element satisfying the predicate was not found in the collection."))
else
result

Comment on lines +627 to +640
let tryFindIndex (f: 'T -> bool) (vector: PersistentVector<'T>) =
let mutable result = -1
let mutable i = 0

while result = -1 && i < vector.Length do
if f vector.[i] then
result <- i

i <- i + 1

if result = -1 then None else Some result

let find (f: 'T -> bool) (vector: PersistentVector<'T>) =
vector.[findIndex f vector]

let tryFind (f: 'T -> bool) (vector: PersistentVector<'T>) =
match tryFindIndex f vector with
| Some i -> Some vector.[i]
| None -> None

let forall (f: 'T -> bool) (vector: PersistentVector<'T>) =
let mutable allMatch = true
let mutable i = 0

while allMatch && i < vector.Length do
if not(f vector.[i]) then
allMatch <- false

i <- i + 1

allMatch

let inline head(vector: PersistentVector<'T>) =
if vector.IsEmpty then
invalidArg "vector" "The input vector was empty."
else
vector.[0]

let inline tryHead(vector: PersistentVector<'T>) =
if vector.IsEmpty then None else Some vector.[0]

let iter (f: 'T -> unit) (vector: PersistentVector<'T>) =
for item in vector do
f item

let iteri (f: int -> 'T -> unit) (vector: PersistentVector<'T>) =
let mutable i = 0

for item in vector do
f i item
i <- i + 1

let ofList(items: 'T list) : PersistentVector<'T> =
let mutable ret = TransientVector()

for item in items do
ret <- ret.conj item

ret.persistent()

let ofSeq(items: 'T seq) =
PersistentVector.ofSeq items

Expand All @@ -601,6 +707,19 @@ module PersistentVector =
let inline singleton(x: 'T) =
empty |> conj x

let toArray(vector: PersistentVector<'T>) =
let arr = Array.zeroCreate vector.Length
let mutable i = 0

for item in vector do
arr.[i] <- item
i <- i + 1
Comment on lines +710 to +716

arr

let toList(vector: PersistentVector<'T>) : 'T list =
foldBack (fun item acc -> item :: acc) vector []

let rangedIterator (startIndex: int) (endIndex: int) (vector: PersistentVector<'T>) =
vector.rangedIterator(startIndex, endIndex)

Expand Down
137 changes: 92 additions & 45 deletions src/FSharpx.Collections/PersistentVector.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -13,144 +13,191 @@ type PersistentVector<'T> =
interface System.Collections.Generic.IReadOnlyCollection<'T>

/// O(1). Returns a new vector with the element added at the end.
member Conj : 'T -> PersistentVector<'T>
member Conj: 'T -> PersistentVector<'T>

/// O(1) for all practical purposes; really O(log32n). Returns a new vector without the last item. If the collection is empty it throws an exception.
member Initial : PersistentVector<'T>
member Initial: PersistentVector<'T>

/// O(1) for all practical purposes; really O(log32n). Returns option vector without the last item.
member TryInitial : PersistentVector<'T> option
member TryInitial: PersistentVector<'T> option

/// O(1). Returns true if the vector has no elements.
member IsEmpty : bool
member IsEmpty: bool

/// O(1). Returns a new PersistentVector with no elements.
static member Empty : unit -> PersistentVector<'T>
static member Empty: unit -> PersistentVector<'T>

/// O(1) for all practical purposes; really O(log32n). Returns vector element at the index.
member Item : int -> 'T with get
member Item: int -> 'T with get

/// O(1). Returns the last element in the vector. If the vector is empty it throws an exception.
member Last : 'T
member Last: 'T

/// O(1). Returns option last element in the vector.
member TryLast : 'T option
member TryLast: 'T option

/// O(1). Returns the number of items in the vector.
member Length : int
member Length: int

/// O(n). Returns random access list reversed.
member Rev : unit -> PersistentVector<'T>
member Rev: unit -> PersistentVector<'T>

/// O(1) for all practical purposes; really O(log32n). Returns tuple last element and vector without last item
member Unconj : PersistentVector<'T> * 'T
member Unconj: PersistentVector<'T> * 'T

/// O(1) for all practical purposes; really O(log32n). Returns option tuple last element and vector without last item
member TryUnconj : (PersistentVector<'T> * 'T) option
member TryUnconj: (PersistentVector<'T> * 'T) option

/// O(1) for all practical purposes; really O(log32n). Returns a new vector that contains the given value at the index.
member Update : int * 'T -> PersistentVector<'T>
member Update: int * 'T -> PersistentVector<'T>

/// O(1) for all practical purposes; really O(log32n). Returns option vector that contains the given value at the index.
member TryUpdate : int * 'T -> PersistentVector<'T> option
member TryUpdate: int * 'T -> PersistentVector<'T> option

/// Defines functions which allow to access and manipulate PersistentVectors.
[<RequireQualifiedAccess>]
module PersistentVector =
//pattern discriminators (active pattern)
val (|Conj|Nil|) : PersistentVector<'T> -> Choice<(PersistentVector<'T> * 'T),unit>
val (|Conj|Nil|): PersistentVector<'T> -> Choice<(PersistentVector<'T> * 'T), unit>

/// O(n). Returns a new vector with the elements of the second vector added at the end.
val append : PersistentVector<'T> -> PersistentVector<'T> -> PersistentVector<'T>
val append: PersistentVector<'T> -> PersistentVector<'T> -> PersistentVector<'T>

/// O(1). Returns a new vector with the element added at the end.
val inline conj : 'T -> PersistentVector<'T> -> PersistentVector<'T>
val inline conj: 'T -> PersistentVector<'T> -> PersistentVector<'T>

/// O(1). Returns vector of no elements.
[<GeneralizableValue>]
val empty<'T> : PersistentVector<'T>

/// O(m,n). Returns a seq from a vector of vectors.
val inline flatten : PersistentVector<PersistentVector<'T>> -> seq<'T>
val inline flatten: PersistentVector<PersistentVector<'T>> -> seq<'T>

/// O(n). Returns a state from the supplied state and a function operating from left to right.
val inline fold : ('State -> 'T -> 'State) -> 'State -> PersistentVector<'T> -> 'State
val inline fold: ('State -> 'T -> 'State) -> 'State -> PersistentVector<'T> -> 'State

/// O(n). Returns a state from the supplied state and a function operating from right to left.
val inline foldBack : ('T -> 'State -> 'State) -> PersistentVector<'T> -> 'State -> 'State
val inline foldBack: ('T -> 'State -> 'State) -> PersistentVector<'T> -> 'State -> 'State

/// O(n). Returns a vector of the supplied length using the supplied function operating on the index.
val init : int -> (int -> 'T) -> PersistentVector<'T>
val init: int -> (int -> 'T) -> PersistentVector<'T>

/// O(1) for all practical purposes; really O(log32n). Returns a new vector without the last item. If the collection is empty it throws an exception.
val inline initial : PersistentVector<'T> -> PersistentVector<'T>
val inline initial: PersistentVector<'T> -> PersistentVector<'T>

/// O(1) for all practical purposes; really O(log32n). Returns option vector without the last item.
val inline tryInitial : PersistentVector<'T> -> PersistentVector<'T> option
val inline tryInitial: PersistentVector<'T> -> PersistentVector<'T> option

/// O(1). Returns true if the vector has no elements.
val inline isEmpty : PersistentVector<'T> -> bool
val inline isEmpty: PersistentVector<'T> -> bool

/// O(1). Returns the last element in the vector. If the vector is empty it throws an exception.
val inline last : PersistentVector<'T> -> 'T
val inline last: PersistentVector<'T> -> 'T

/// O(1). Returns option last element in the vector.
val inline tryLast : PersistentVector<'T> -> 'T option
val inline tryLast: PersistentVector<'T> -> 'T option

/// O(1). Returns the number of items in the vector.
val inline length : PersistentVector<'T> -> int
val inline length: PersistentVector<'T> -> int

/// O(n). Returns a vector whose elements are the results of applying the supplied function to each of the elements of a supplied vector.
val map : ('T -> 'T1) -> PersistentVector<'T> -> PersistentVector<'T1>
val map: ('T -> 'T1) -> PersistentVector<'T> -> PersistentVector<'T1>

/// O(n). Returns a vector whose elements are the results of applying the supplied function to each of the indices and elements of a supplied vector.
val mapi : (int -> 'T -> 'T1) -> PersistentVector<'T> -> PersistentVector<'T1>
val mapi: (int -> 'T -> 'T1) -> PersistentVector<'T> -> PersistentVector<'T1>

/// O(1) for all practical purposes; really O(log32n). Returns the value at the index. If the index is out of bounds it throws an exception.
val inline nth : int -> PersistentVector<'T> -> 'T
val inline nth: int -> PersistentVector<'T> -> 'T

/// O(log32(m,n)). Returns the value at the outer index, inner index. If either index is out of bounds it throws an exception.
val inline nthNth : int -> int -> PersistentVector<PersistentVector<'T>> -> 'T
val inline nthNth: int -> int -> PersistentVector<PersistentVector<'T>> -> 'T

/// O(1) for all practical purposes; really O(log32n). Returns option value at the index.
val inline tryNth : int -> PersistentVector<'T> -> 'T option
val inline tryNth: int -> PersistentVector<'T> -> 'T option

/// O(log32(m,n)). Returns option value at the indices.
val inline tryNthNth : int -> int -> PersistentVector<PersistentVector<'T>> -> 'T option
val inline tryNthNth: int -> int -> PersistentVector<PersistentVector<'T>> -> 'T option

/// O(n). Returns a new vector containing only elements for which the supplied function returns Some.
val choose: ('T -> 'T1 option) -> PersistentVector<'T> -> PersistentVector<'T1>

/// O(n). Returns true if the given predicate returns true for some element in the vector.
val exists: ('T -> bool) -> PersistentVector<'T> -> bool

/// O(n). Returns a new vector containing only the elements of the supplied vector for which the given predicate returns true.
val filter: ('T -> bool) -> PersistentVector<'T> -> PersistentVector<'T>

/// O(n). Returns the index of the first element in the vector that satisfies the given predicate. Raises KeyNotFoundException if not found.
val findIndex: ('T -> bool) -> PersistentVector<'T> -> int

/// O(n). Returns the first element in the vector that satisfies the given predicate. Raises KeyNotFoundException if not found.
val find: ('T -> bool) -> PersistentVector<'T> -> 'T

/// O(n). Returns true if the given predicate returns true for all elements in the vector.
val forall: ('T -> bool) -> PersistentVector<'T> -> bool

/// O(1) for all practical purposes; really O(log32n). Returns the first element in the vector. Raises ArgumentException if the vector is empty.
val inline head: PersistentVector<'T> -> 'T

/// O(n). Applies the given function to each element of the vector.
val iter: ('T -> unit) -> PersistentVector<'T> -> unit

/// O(n). Applies the given function to each element of the vector, passing the index as the first argument.
val iteri: (int -> 'T -> unit) -> PersistentVector<'T> -> unit

/// O(n). Returns a new vector from the supplied list.
val ofList: 'T list -> PersistentVector<'T>

/// O(n). Returns a vector of the seq.
val ofSeq : seq<'T> -> PersistentVector<'T>
val ofSeq: seq<'T> -> PersistentVector<'T>

/// O(n). Returns vector reversed.
val inline rev : PersistentVector<'T> -> PersistentVector<'T>
val inline rev: PersistentVector<'T> -> PersistentVector<'T>

/// O(1). Returns a new vector of one element.
val inline singleton : 'T -> PersistentVector<'T>
val inline singleton: 'T -> PersistentVector<'T>

/// O(n). Views a subset of the given vector. startIndex is inclusive, endIndex is exclusive.
/// `rangedIterator 0 count` is the same as toSeq
val rangedIterator : int -> int -> PersistentVector<'T> -> seq<'T>
val rangedIterator: int -> int -> PersistentVector<'T> -> seq<'T>

/// O(n). Returns the elements of the vector as an array.
val toArray: PersistentVector<'T> -> 'T[]

/// O(n). Returns the elements of the vector as a list.
val toList: PersistentVector<'T> -> 'T list

/// O(n). Views the given vector as a sequence.
val inline toSeq : PersistentVector<'T> -> seq<'T>
val inline toSeq: PersistentVector<'T> -> seq<'T>

/// O(n). Returns the index of the first element in the vector that satisfies the given predicate, or None if not found.
val tryFindIndex: ('T -> bool) -> PersistentVector<'T> -> int option

/// O(n). Returns the first element in the vector that satisfies the given predicate, or None if not found.
val tryFind: ('T -> bool) -> PersistentVector<'T> -> 'T option

/// O(1) for all practical purposes; really O(log32n). Returns option first element in the vector.
val inline tryHead: PersistentVector<'T> -> 'T option

/// O(1) for all practical purposes; really O(log32n). Returns tuple last element and vector without last item
val inline unconj : PersistentVector<'T> -> PersistentVector<'T> * 'T
val inline unconj: PersistentVector<'T> -> PersistentVector<'T> * 'T

/// O(1) for all practical purposes; really O(log32n). Returns option tuple last element and vector without last item
val inline tryUnconj : PersistentVector<'T> -> (PersistentVector<'T> * 'T) option
val inline tryUnconj: PersistentVector<'T> -> (PersistentVector<'T> * 'T) option

/// O(1) for all practical purposes; really O(log32n). Returns a new vector that contains the given value at the index.
val inline update : int -> 'T -> PersistentVector<'T> -> PersistentVector<'T>
val inline update: int -> 'T -> PersistentVector<'T> -> PersistentVector<'T>

/// O(log32(m,n)). Returns a new vector of vectors that contains the given value at the indices.
val inline updateNth : int -> int -> 'T -> PersistentVector<PersistentVector<'T>> -> PersistentVector<PersistentVector<'T>>
val inline updateNth:
int -> int -> 'T -> PersistentVector<PersistentVector<'T>> -> PersistentVector<PersistentVector<'T>>

/// O(1) for all practical purposes; really O(log32n). Returns option vector that contains the given value at the index.
val inline tryUpdate : int -> 'T -> PersistentVector<'T> -> PersistentVector<'T> option
val inline tryUpdate: int -> 'T -> PersistentVector<'T> -> PersistentVector<'T> option

/// O(log32(m,n)). Returns option vector that contains the given value at the indices.
val inline tryUpdateNth : int -> int -> 'T -> PersistentVector<PersistentVector<'T>> -> PersistentVector<PersistentVector<'T>> option
val inline tryUpdateNth:
int -> int -> 'T -> PersistentVector<PersistentVector<'T>> -> PersistentVector<PersistentVector<'T>> option

/// O(n). Returns a vector of vectors of given length from the seq. Result may be a jagged vector.
val inline windowSeq : int -> seq<'T> -> PersistentVector<PersistentVector<'T>>
val inline windowSeq: int -> seq<'T> -> PersistentVector<PersistentVector<'T>>
Loading
Loading