Skip to content

Instantly share code, notes, and snippets.

@mwyrebski
Created November 19, 2019 19:44
Show Gist options
  • Save mwyrebski/32282c7d206b061c722c5610f15795f2 to your computer and use it in GitHub Desktop.
Save mwyrebski/32282c7d206b061c722c5610f15795f2 to your computer and use it in GitHub Desktop.
Simple implementation of pagination function
module Seq =
/// Skips given count from source or returns empty sequence if skip is beyond the limits.
let safeSkip count source =
source
|> Seq.indexed
|> Seq.skipWhile (fun (i, _) -> i < count)
|> Seq.map snd
/// Takes given count from source or returns empty sequence. An alias for the `truncate`.
let safeTake = Seq.truncate
/// Returns elements from source sequence for provided offset and limit.
/// Negative offset behaves like zero offset.
/// Negative limit produces empty sequence.
let paged offset limit source =
source
|> safeSkip offset
|> safeTake limit
// -----------------------------------------
// Tests
let (===) x y = if x = y then printfn "Ok" else eprintf "Error (x: %A, y: %A)" x y
let input = [ 'a'..'e' ]
Seq.paged 0 0 input |> Seq.toList === []
Seq.paged 0 5 input |> Seq.toList === [ 'a'..'e' ]
Seq.paged 0 1 input |> Seq.toList === [ 'a' ]
Seq.paged 4 1 input |> Seq.toList === [ 'e' ]
Seq.paged 5 1 input |> Seq.toList === []
Seq.paged -2 2 input |> Seq.toList === [ 'a'..'b' ]
Seq.paged 0 -2 input |> Seq.toList === []
Seq.paged 20 2 input |> Seq.toList === []
Seq.paged 2 20 input |> Seq.toList === [ 'c'..'e' ]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment