This library comes with some additional numeric functions and constants.

These functions work over many numeric types

```
let qr0 = divRem 7 3 //val qr0 : int * int = (2, 1)
let qr1 = divRem 7I 3I //val qr1 : System.Numerics.BigInteger * System.Numerics.BigInteger = (2, 1)
let qr2 = divRem 7. 3. //val qr2 : float * float = (2.333333333, 0.0) -> using default method.
```

Apart from typical math constants, bounded types comes with `minValue`

and `maxValue`

constants.

Here's an example how can this be used to implement an efficient `findMin`

function

```
let inline findMin (lst: 'a list) =
let rec loop acc = function
| [] -> acc
| x::_ when x = minValue -> x
| x::xs -> loop (if x < acc then x else acc) xs
loop maxValue lst
let minInt = findMin [1;0;12;2]
let minUInt = findMin [1u;0u;12u;2u] // loops only twice
```

Writing code that is generic over different numeric types can be really tedious in F#.

Using this library it becomes an easy task, but it's important to understand the numeric abstractions and its limitations.

In order to have a reasonable type inference over generic types we need strict operations.

For example the F# definition of `(+)`

can take 2 different types, this makes possible to interact with some .NET types that have defined the `(+)`

operator in a very arbitrary way.

For instance you can add a `float`

to a `DateTime`

with the `(+)`

operator, and that `float`

will be interpreted as seconds.

By opening the `FSharpPlus.Math.Generic`

namespace this will no longer be possible, because that's the tradeoff in order to get decent type inference.

Numbers with a G suffix are generics.

```
open FSharpPlus.Math.Generic
let res5Int : int = 5G
let res5UInt : uint32 = 5G
```

Often you need to define generic constants when defining generic functions. Since there is no way to define generic decimal literals in F# at the moment of writing this, we can use divisions:

```
let inline areaOfCircle radio =
let pi =
314159265358979323846264338G
/
100000000000000000000000000G
pi * radio * radio
let area1 = areaOfCircle 5.
let area2 = areaOfCircle 5.0f
let area3 = areaOfCircle 5.0M
```

```
type Vector2d<'T> = Vector2d of 'T * 'T with
static member inline (+) (Vector2d(a:'t, b:'t), Vector2d(c:'t, d:'t)) = Vector2d (((a + c):'t), ((b + d):'t))
static member inline (-) (Vector2d(a:'t, b:'t), Vector2d(c:'t, d:'t)) = Vector2d (((a - c):'t), ((b - d):'t))
static member inline (*) (Vector2d(a:'t, b:'t), Vector2d(c:'t, d:'t)) = Vector2d (((a * c):'t), ((b * d):'t))
static member Return x = Vector2d (x, x)
static member Map(Vector2d(x, y), f) = Vector2d (f x, f y)
static member inline FromBigInt x = let y = fromBigInt x in Vector2d (y, y)
```

Note we don't define overloads for adding a vector to a number

Why? Apart from being tedious they will break math operators strictness

so we will have problems type inferencing generic functions.

OK, but then how to add (subtract, multiply) to a number?

Option 1, explicitely 'lift' the number.

Requires Return and ( + , - , * )

```
let x1 = Vector2d (32,5) + result 7
let x1' = result 7 + Vector2d (32,5)
```

Option 2, use Generic Numbers

Requires `FromBigInt`

and (+,-,*,/)

```
open FSharpPlus.Math.Generic
let x2 = Vector2d (32,5) + 7G
let x2' = 7G + Vector2d (32,5)
```

Option 3, use Applicative Math Operators
Requires only `Map`

```
open FSharpPlus.Math.Applicative
let x3 = Vector2d (32,5) .+ 7
let x3' = 7 +. Vector2d (32,5)
```

We may use types defined in other libraries, let's suppose we have this type Ratio defined somewhere.

```
type Ratio =
struct
val Numerator : bigint
val Denominator : bigint
new (numerator: bigint, denominator: bigint) = {Numerator = numerator; Denominator = denominator}
end
override this.ToString() = this.Numerator.ToString() + " % " + this.Denominator.ToString()
let ratio (a:bigint) (b:bigint) :Ratio =
if b = 0I then failwith "Ratio.%: zero denominator"
let a, b = if b < 0I then (-a, -b) else (a, b)
let gcd = gcd a b
Ratio (a / gcd, b / gcd)
let Ratio (x,y) = x </ratio/> y
type Ratio with
static member inline (/) (a:Ratio, b:Ratio) = (a.Numerator * b.Denominator) </ratio/> (a.Denominator * b.Numerator)
static member inline (+) (a:Ratio, b:Ratio) = (a.Numerator * b.Denominator + b.Numerator * a.Denominator) </ratio/> (a.Denominator * b.Denominator)
static member inline (-) (a:Ratio, b:Ratio) = (a.Numerator * b.Denominator - b.Numerator * a.Denominator) </ratio/> (a.Denominator * b.Denominator)
static member inline (*) (a:Ratio, b:Ratio) = (a.Numerator * b.Numerator) </ratio/> (a.Denominator * b.Denominator)
static member inline Abs (r:Ratio) = (abs r.Numerator) </ratio/> r.Denominator
static member inline Signum (r:Ratio) = (signum r.Numerator) </ratio/> 1I
static member inline FromBigInt (x:bigint) = fromBigInt x </ratio/> 1I
static member inline (~-) (r:Ratio) = -(r.Numerator) </ratio/> r.Denominator
```

Since most Rational implementations have Numerator and Denominator defined we can just use our generic functions on it:

```
let some3_2 = trySqrt (Ratio(9I, 4I))
```

The quadratic function has different results depending on which domain it operates.

For example for real numbers it can have 0 or 2 solutions (arguably also 1 that is a double solution).

But for complex numbers it always has 2 solutions.

```
open FSharpPlus.Math.Generic
let inline quadratic a b c =
let root1 = ( -b + sqrt ( b * b - 4G * a * c) ) / (2G * a)
let root2 = ( -b - sqrt ( b * b - 4G * a * c) ) / (2G * a)
(root1,root2)
let noRes = quadratic 2.0 3G 9G
// val noRes : float * float = (nan, nan)
let res30_15 = quadratic 2.0 -3G -9G
// val res30_15 : float * float = (3.0, -1.5)
let res30_15f = quadratic 2.0f -3G -9G
// val res30_15f : float32 * float32 = (3.0f, -1.5f)
let resCmplx:System.Numerics.Complex * _ = quadratic 2G -3G 9G
// val resCmplx : System.Numerics.Complex * System.Numerics.Complex = ((0.75, -1.98431348329844), (0.75, 1.98431348329844))
let res30_15r:Ratio * _ = quadratic 2G -3G -9G
// val res30_15r : Ratio * Ratio = (3 % 1, -3 % 2)
```

namespace FSharpPlus

val qr0 : int * int

val divRem : dividend:'Num -> divisor:'Num -> 'Num * 'Num (requires member DivRem)

val qr1 : System.Numerics.BigInteger * System.Numerics.BigInteger

val qr2 : float * float

val findMin : lst:'a list -> 'a (requires member MinValue and member MaxValue and comparison)

val lst : 'a list (requires member MinValue and member MaxValue and comparison)

type 'T list = List<'T>

val loop : ('a -> 'a list -> 'a) (requires member MinValue and member MaxValue and comparison)

val acc : 'a (requires member MinValue and member MaxValue and comparison)

val x : 'a (requires member MinValue and member MaxValue and comparison)

val minValue<'Num (requires member MinValue)> : 'Num (requires member MinValue)

val xs : 'a list (requires member MinValue and member MaxValue and comparison)

val maxValue<'Num (requires member MaxValue)> : 'Num (requires member MaxValue)

val minInt : int

val minUInt : uint32

namespace FSharpPlus.Math

module Generic

from FSharpPlus.Math

from FSharpPlus.Math

val res5Int : int

Multiple items

val int : value:'T -> int (requires member op_Explicit)

--------------------

type int = int32

--------------------

type int<'Measure> = int

val int : value:'T -> int (requires member op_Explicit)

--------------------

type int = int32

--------------------

type int<'Measure> = int

val res5UInt : uint32

Multiple items

val uint32 : value:'T -> uint32 (requires member op_Explicit)

--------------------

type uint32 = System.UInt32

val uint32 : value:'T -> uint32 (requires member op_Explicit)

--------------------

type uint32 = System.UInt32

val areaOfCircle : radio:'a -> 'a (requires member ( * ) and member ( / ) and member FromBigInt)

val radio : 'a (requires member ( * ) and member ( / ) and member FromBigInt)

val pi : 'a (requires member ( * ) and member ( / ) and member FromBigInt)

val area1 : float

val area2 : float32

val area3 : decimal

Multiple items

union case Vector2d.Vector2d: 'T * 'T -> Vector2d<'T>

--------------------

type Vector2d<'T> =

| Vector2d of 'T * 'T

static member FromBigInt : x:bigint -> Vector2d<'a> (requires member FromBigInt)

static member Map : Vector2d<'a> * f:('a -> 'b) -> Vector2d<'b>

static member Return : x:'a -> Vector2d<'a>

static member ( + ) : Vector2d<'t> * Vector2d<'t> -> Vector2d<'t> (requires member ( + ))

static member ( * ) : Vector2d<'t> * Vector2d<'t> -> Vector2d<'t> (requires member ( * ))

static member ( - ) : Vector2d<'t> * Vector2d<'t> -> Vector2d<'t> (requires member ( - ))

union case Vector2d.Vector2d: 'T * 'T -> Vector2d<'T>

--------------------

type Vector2d<'T> =

| Vector2d of 'T * 'T

static member FromBigInt : x:bigint -> Vector2d<'a> (requires member FromBigInt)

static member Map : Vector2d<'a> * f:('a -> 'b) -> Vector2d<'b>

static member Return : x:'a -> Vector2d<'a>

static member ( + ) : Vector2d<'t> * Vector2d<'t> -> Vector2d<'t> (requires member ( + ))

static member ( * ) : Vector2d<'t> * Vector2d<'t> -> Vector2d<'t> (requires member ( * ))

static member ( - ) : Vector2d<'t> * Vector2d<'t> -> Vector2d<'t> (requires member ( - ))

val a : 't (requires member ( + ))

val b : 't (requires member ( + ))

val c : 't (requires member ( + ))

val d : 't (requires member ( + ))

val a : 't (requires member ( - ))

val b : 't (requires member ( - ))

val c : 't (requires member ( - ))

val d : 't (requires member ( - ))

val a : 't (requires member ( * ))

val b : 't (requires member ( * ))

val c : 't (requires member ( * ))

val d : 't (requires member ( * ))

val x : 'a

Multiple items

module Map

from FSharpPlus

--------------------

module Map

from Microsoft.FSharp.Collections

--------------------

type Map<'Key,'Value (requires comparison)> =

interface IReadOnlyDictionary<'Key,'Value>

interface IReadOnlyCollection<KeyValuePair<'Key,'Value>>

interface IEnumerable

interface IComparable

interface IEnumerable<KeyValuePair<'Key,'Value>>

interface ICollection<KeyValuePair<'Key,'Value>>

interface IDictionary<'Key,'Value>

new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>

member Add : key:'Key * value:'Value -> Map<'Key,'Value>

member ContainsKey : key:'Key -> bool

...

--------------------

new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>

module Map

from FSharpPlus

--------------------

module Map

from Microsoft.FSharp.Collections

--------------------

type Map<'Key,'Value (requires comparison)> =

interface IReadOnlyDictionary<'Key,'Value>

interface IReadOnlyCollection<KeyValuePair<'Key,'Value>>

interface IEnumerable

interface IComparable

interface IEnumerable<KeyValuePair<'Key,'Value>>

interface ICollection<KeyValuePair<'Key,'Value>>

interface IDictionary<'Key,'Value>

new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>

member Add : key:'Key * value:'Value -> Map<'Key,'Value>

member ContainsKey : key:'Key -> bool

...

--------------------

new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>

val y : 'a

val f : ('a -> 'b)

val x : bigint

val y : 'a (requires member FromBigInt)

val fromBigInt : x:bigint -> 'Num (requires member FromBigInt)

val x1 : Vector2d<int>

val result : x:'T -> 'Functor<'T> (requires member Return)

val x1' : Vector2d<int>

val x2 : Vector2d<int>

val x2' : Vector2d<int>

module Applicative

from FSharpPlus.Math

from FSharpPlus.Math

val x3 : Vector2d<int>

val x3' : Vector2d<int>

Ratio.Numerator: bigint

type bigint = System.Numerics.BigInteger

Ratio.Denominator: bigint

val numerator : bigint

val denominator : bigint

val this : inref<Ratio>

val ratio : a:bigint -> b:bigint -> Ratio

val a : bigint

val b : bigint

Multiple items

type Ratio =

struct

new : numerator:bigint * denominator:bigint -> Ratio

val Numerator: bigint

val Denominator: bigint

override ToString : unit -> string

static member Abs : r:Ratio -> Ratio

static member FromBigInt : x:bigint -> Ratio

static member Signum : r:Ratio -> Ratio

static member ( + ) : a:Ratio * b:Ratio -> Ratio

static member ( / ) : a:Ratio * b:Ratio -> Ratio

static member ( * ) : a:Ratio * b:Ratio -> Ratio

...

end

--------------------

Ratio ()

new : numerator:bigint * denominator:bigint -> Ratio

type Ratio =

struct

new : numerator:bigint * denominator:bigint -> Ratio

val Numerator: bigint

val Denominator: bigint

override ToString : unit -> string

static member Abs : r:Ratio -> Ratio

static member FromBigInt : x:bigint -> Ratio

static member Signum : r:Ratio -> Ratio

static member ( + ) : a:Ratio * b:Ratio -> Ratio

static member ( / ) : a:Ratio * b:Ratio -> Ratio

static member ( * ) : a:Ratio * b:Ratio -> Ratio

...

end

--------------------

Ratio ()

new : numerator:bigint * denominator:bigint -> Ratio

val failwith : message:string -> 'T

val gcd : bigint

Multiple items

val Ratio : x:bigint * y:bigint -> Ratio

--------------------

type Ratio =

struct

new : numerator:bigint * denominator:bigint -> Ratio

val Numerator: bigint

val Denominator: bigint

override ToString : unit -> string

static member Abs : r:Ratio -> Ratio

static member FromBigInt : x:bigint -> Ratio

static member Signum : r:Ratio -> Ratio

static member ( + ) : a:Ratio * b:Ratio -> Ratio

static member ( / ) : a:Ratio * b:Ratio -> Ratio

static member ( * ) : a:Ratio * b:Ratio -> Ratio

...

end

--------------------

Ratio ()

new : numerator:bigint * denominator:bigint -> Ratio

val Ratio : x:bigint * y:bigint -> Ratio

--------------------

type Ratio =

struct

new : numerator:bigint * denominator:bigint -> Ratio

val Numerator: bigint

val Denominator: bigint

override ToString : unit -> string

static member Abs : r:Ratio -> Ratio

static member FromBigInt : x:bigint -> Ratio

static member Signum : r:Ratio -> Ratio

static member ( + ) : a:Ratio * b:Ratio -> Ratio

static member ( / ) : a:Ratio * b:Ratio -> Ratio

static member ( * ) : a:Ratio * b:Ratio -> Ratio

...

end

--------------------

Ratio ()

new : numerator:bigint * denominator:bigint -> Ratio

val y : bigint

val a : Ratio

val b : Ratio

val r : Ratio

val abs : value:'Num -> 'Num (requires member Abs)

val signum : value:'Num -> 'Num (requires member Signum)

val some3_2 : Ratio option

val trySqrt : x:'a -> 'a option (requires member TrySqrt)

val quadratic : a:'a -> b:'a -> c:'a -> 'a * 'a (requires member FromInt32 and member ( * ) and member Sqrt and member ( ~- ) and member ( / ) and member ( + ) and member ( - ))

val a : 'a (requires member FromInt32 and member ( * ) and member Sqrt and member ( ~- ) and member ( / ) and member ( + ) and member ( - ))

val b : 'a (requires member FromInt32 and member ( * ) and member Sqrt and member ( ~- ) and member ( / ) and member ( + ) and member ( - ))

val c : 'a (requires member FromInt32 and member ( * ) and member Sqrt and member ( ~- ) and member ( / ) and member ( + ) and member ( - ))

val root1 : 'a (requires member FromInt32 and member ( * ) and member Sqrt and member ( ~- ) and member ( / ) and member ( + ) and member ( - ))

val sqrt : x:'b -> 'b (requires member Sqrt)

val root2 : 'a (requires member FromInt32 and member ( * ) and member Sqrt and member ( ~- ) and member ( / ) and member ( + ) and member ( - ))

val noRes : float * float

val res30_15 : float * float

val res30_15f : float32 * float32

val resCmplx : System.Numerics.Complex * System.Numerics.Complex

namespace System

namespace System.Numerics

Multiple items

type Complex =

struct

new : real:float * imaginary:float -> Complex

member Equals : obj:obj -> bool + 1 overload

member GetHashCode : unit -> int

member Imaginary : float

member Magnitude : float

member Phase : float

member Real : float

member ToString : unit -> string + 3 overloads

static val Zero : Complex

static val One : Complex

...

end

--------------------

System.Numerics.Complex ()

System.Numerics.Complex(real: float, imaginary: float) : System.Numerics.Complex

type Complex =

struct

new : real:float * imaginary:float -> Complex

member Equals : obj:obj -> bool + 1 overload

member GetHashCode : unit -> int

member Imaginary : float

member Magnitude : float

member Phase : float

member Real : float

member ToString : unit -> string + 3 overloads

static val Zero : Complex

static val One : Complex

...

end

--------------------

System.Numerics.Complex ()

System.Numerics.Complex(real: float, imaginary: float) : System.Numerics.Complex

val res30_15r : Ratio * Ratio