8000 GitHub - ieviev/fsil: F# inline generic library
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
8000

ieviev/fsil

Repository files navigation

fsil: F# inline library

Nuget

Features:

  • a small generic utils library like FSharpPlus
  • all functions are inline and trimmable, won't bloat your binary size: you pay for only what you use
  • Fable compatible
  • zero cost: does not create junk variables or implicit allocations
  • uses [<AutoOpen>] so all functions are in the global namespace

Example:

Benchmark comparisons to FSharpPlus

I love F# for high performance programming and this makes high-level generic F# a little more feasible without punishing the user performance-wise. The functions in this library compile down to exactly the same form as the (optimal) resolved implementation so iter f x to the compiler is identical to e.g., ValueOption.iter f x or Array.iter f x.

Currently this library contains a fairly small set of functions:

iter, iteri, iter_range, map, mapi, is_some, is_none, is_ok, some, none, try_item, value, len, enum, enumv, default_, default_inst, default_with, zero, one, print, forall, exists, fold, foldi.

there are also some functions for spans with separate function definitions due to their limitations:

span_forall, span_exists, span_iter...

You can also define your own implementations as static members. here is an example for iter and map on a Tree, for documentation just look at the source code itself.

type Tree<'T> =
    | Leaf of 'T
    | Node of 'T * Tree<'T> * Tree<'T>

    static member Map(self: Tree<'T>, fn: 'T -> 'U) : Tree<'U> =
        match self with
        | Leaf x -> Leaf(fn x)
        | Node(v, l, r) ->
            let new_l = Tree.Map(l, fn)
            let new_r = Tree.Map(r, fn)
            Node(fn v, new_l, new_r)

    static member Iterate(self: Tree<'T>, fn: 'T -> unit) : unit =
        match self with
        | Leaf x -> fn x
        | Node(v, l, r) ->
            Tree.Iterate(l, fn)
            fn v
            Tree.Iterate(r, fn)

    static member IterateWhile(self: Tree<'T>, cond: byref<bool>, fn: 'T -> unit) : unit =
        if cond then
            match self with
            | Leaf x -> fn x
            | Node(v, l, r) ->
                Tree.IterateWhile(l, &cond, fn)
                if cond then fn v
                if cond then Tree.IterateWhile(r, &cond, fn)

let tree1 = Leaf 1
let iter = tree1 |> iter (fun v -> print v)
let mapped: Tree<int> = tree1 |> map (fun v -> v + 1)
// these implementations are generated from Iterate/IterateWhile/Map
// so you get them all "for free"
let map_indexed = tree1 |> mapi (fun idx v -> $"elem {idx}:{v}")
let sum: int = tree1 |> fold 0 (fun acc v -> acc + v)
let exists2: bool = tree1 |> exists (fun v -> v = 2)
let all_larger_than_5: bool = tree1 |> forall (fun v -> v > 5)
let find_5: voption<int> = tree1 |> try_find (fun v -> v = 5)

or you can extend these definitions to your own general functions

// flattening a list is just binding to id
// this function now works on any collection you can bind
let inline flatten list = list |> bind id 

let flatarray = flatten [|[|1;2;3|];[|4;5;6|]|] // [|1;2;3;4;5;6|]
let flatlist = flatten [[1;2;3];[4;5;6]]  // [1;2;3;4;5;6]
let flatoption = flatten (Some(Some 1)) // Some 1

Most important remember to have (f#)un! :)

About

F# inline generic library

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

0