4 people like it.

Generic number literal

A generic numeral G. It allows writing functions for arbitrary numeric type. The transformation is an efficient one, because it is implemented explicitly for every type. It combines the type classes technique of FsControl (https://github.com/gmpl/FsControl and http://nut-cracker.azurewebsites.net/typeclasses-for-fsharp) with numeric literals. But FsControl is removed to completely avoid unnecessary function calls.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
43: 
44: 
45: 
46: 
47: 
48: 
open System.Numerics
// optional
open MathNet.Numerics

[<AutoOpen>]
module NumericLiteralG = 
    type GenericNumber = GenericNumber with
        static member inline genericNumber (x:int32, _:int8) = int8 x
        static member inline genericNumber (x:int32, _:uint8) = uint8 x
        static member inline genericNumber (x:int32, _:int16) = int16 x
        static member inline genericNumber (x:int32, _:uint16) = uint16 x
        static member inline genericNumber (x:int32, _:int32) = x
        static member inline genericNumber (x:int32, _:uint32) = uint32 x
        static member inline genericNumber (x:int32, _:int64) = int64 x
        static member inline genericNumber (x:int32, _:uint64) = uint64 x
        static member inline genericNumber (x:int32, _:float32) = float32 x
        static member inline genericNumber (x:int32, _:float) = float x
        static member inline genericNumber (x:int32, _:bigint) = bigint x
        static member inline genericNumber (x:int32, _:decimal) = decimal x
        static member inline genericNumber (x:int32, _:Complex) = Complex.op_Implicit x
        static member inline genericNumber (x:int64, _:int64) = int64 x
        static member inline genericNumber (x:int64, _:uint64) = uint64 x
        static member inline genericNumber (x:int64, _:float32) = float32 x
        static member inline genericNumber (x:int64, _:float) = float x
        static member inline genericNumber (x:int64, _:bigint) = bigint x
        static member inline genericNumber (x:int64, _:decimal) = decimal x
        static member inline genericNumber (x:int64, _:Complex) = Complex.op_Implicit x
        static member inline genericNumber (x:string, _:float32) = float32 x
        static member inline genericNumber (x:string, _:float) = float x
        static member inline genericNumber (x:string, _:bigint) = bigint.Parse x
        static member inline genericNumber (x:string, _:decimal) = decimal x
        static member inline genericNumber (x:string, _:Complex) = Complex(float x, 0.0)
        // MathNet.Numerics
        static member inline genericNumber (x:int32, _:Complex32) = Complex32.op_Implicit x
        static member inline genericNumber (x:int32, _:bignum) = bignum.FromInt x
        static member inline genericNumber (x:int64, _:Complex32) = Complex32.op_Implicit x
        static member inline genericNumber (x:int64, _:bignum) = bignum.FromBigInt (bigint x)
        static member inline genericNumber (x:string, _:Complex32) = Complex32(float32 x, 0.0f)
        static member inline genericNumber (x:string, _:bignum) = bignum.FromBigInt (bigint.Parse x)

    let inline instance (a: ^a, b: ^b, c: ^c) = ((^a or ^b or ^c) : (static member genericNumber: ^b * ^c -> ^c) (b, c))
    let inline genericNumber num = instance (GenericNumber, num, Unchecked.defaultof<'b>)

    let inline FromZero () = LanguagePrimitives.GenericZero
    let inline FromOne () = LanguagePrimitives.GenericOne
    let inline FromInt32 n = genericNumber n
    let inline FromInt64 n = genericNumber n
    let inline FromString n = genericNumber n
namespace System
namespace System.Numerics
namespace MathNet
namespace MathNet.Numerics
Multiple items
type AutoOpenAttribute =
  inherit Attribute
  new : unit -> AutoOpenAttribute
  new : path:string -> AutoOpenAttribute
  member Path : string

Full name: Microsoft.FSharp.Core.AutoOpenAttribute

--------------------
new : unit -> AutoOpenAttribute
new : path:string -> AutoOpenAttribute
module NumericLiteralG

from Script
Multiple items
union case GenericNumber.GenericNumber: GenericNumber

--------------------
type GenericNumber =
  | GenericNumber
  static member genericNumber : x:int32 * int8 -> sbyte
  static member genericNumber : x:int32 * uint8 -> byte
  static member genericNumber : x:int32 * int16 -> int16
  static member genericNumber : x:int32 * uint16 -> uint16
  static member genericNumber : x:int32 * int32 -> int32
  static member genericNumber : x:int32 * uint32 -> uint32
  static member genericNumber : x:int32 * int64 -> int64
  static member genericNumber : x:int32 * uint64 -> uint64
  static member genericNumber : x:int32 * float32 -> float32
  static member genericNumber : x:int32 * float -> float
  static member genericNumber : x:int32 * bigint -> BigInteger
  static member genericNumber : x:int32 * decimal -> decimal
  static member genericNumber : x:int32 * Complex -> Complex
  static member genericNumber : x:int64 * int64 -> int64
  static member genericNumber : x:int64 * uint64 -> uint64
  static member genericNumber : x:int64 * float32 -> float32
  static member genericNumber : x:int64 * float -> float
  static member genericNumber : x:int64 * bigint -> BigInteger
  static member genericNumber : x:int64 * decimal -> decimal
  static member genericNumber : x:int64 * Complex -> Complex
  static member genericNumber : x:string * float32 -> float32
  static member genericNumber : x:string * float -> float
  static member genericNumber : x:string * bigint -> BigInteger
  static member genericNumber : x:string * decimal -> decimal
  static member genericNumber : x:string * Complex -> Complex
  static member genericNumber : x:int32 * Complex32 -> Complex32
  static member genericNumber : x:int32 * bignum -> BigRational
  static member genericNumber : x:int64 * Complex32 -> Complex32
  static member genericNumber : x:int64 * bignum -> BigRational
  static member genericNumber : x:string * Complex32 -> Complex32
  static member genericNumber : x:string * bignum -> BigRational

Full name: Script.NumericLiteralG.GenericNumber
static member GenericNumber.genericNumber : x:int32 * int8 -> sbyte

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
val x : int32
Multiple items
val int32 : value:'T -> int32 (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.int32

--------------------
type int32 = System.Int32

Full name: Microsoft.FSharp.Core.int32
Multiple items
val int8 : value:'T -> sbyte (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.int8

--------------------
type int8 = System.SByte

Full name: Microsoft.FSharp.Core.int8
static member GenericNumber.genericNumber : x:int32 * uint8 -> byte

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
Multiple items
val uint8 : value:'T -> byte (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.uint8

--------------------
type uint8 = System.Byte

Full name: Microsoft.FSharp.Core.uint8
static member GenericNumber.genericNumber : x:int32 * int16 -> int16

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
Multiple items
val int16 : value:'T -> int16 (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.int16

--------------------
type int16 = System.Int16

Full name: Microsoft.FSharp.Core.int16

--------------------
type int16<'Measure> = int16

Full name: Microsoft.FSharp.Core.int16<_>
static member GenericNumber.genericNumber : x:int32 * uint16 -> uint16

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
Multiple items
val uint16 : value:'T -> uint16 (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.uint16

--------------------
type uint16 = System.UInt16

Full name: Microsoft.FSharp.Core.uint16
static member GenericNumber.genericNumber : x:int32 * int32 -> int32

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
static member GenericNumber.genericNumber : x:int32 * uint32 -> uint32

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
Multiple items
val uint32 : value:'T -> uint32 (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.uint32

--------------------
type uint32 = System.UInt32

Full name: Microsoft.FSharp.Core.uint32
static member GenericNumber.genericNumber : x:int32 * int64 -> int64

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
Multiple items
val int64 : value:'T -> int64 (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.int64

--------------------
type int64 = System.Int64

Full name: Microsoft.FSharp.Core.int64

--------------------
type int64<'Measure> = int64

Full name: Microsoft.FSharp.Core.int64<_>
static member GenericNumber.genericNumber : x:int32 * uint64 -> uint64

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
Multiple items
val uint64 : value:'T -> uint64 (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.uint64

--------------------
type uint64 = System.UInt64

Full name: Microsoft.FSharp.Core.uint64
static member GenericNumber.genericNumber : x:int32 * float32 -> float32

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
Multiple items
val float32 : value:'T -> float32 (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.float32

--------------------
type float32 = System.Single

Full name: Microsoft.FSharp.Core.float32

--------------------
type float32<'Measure> = float32

Full name: Microsoft.FSharp.Core.float32<_>
static member GenericNumber.genericNumber : x:int32 * float -> float

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
Multiple items
val float : value:'T -> float (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.float

--------------------
type float = System.Double

Full name: Microsoft.FSharp.Core.float

--------------------
type float<'Measure> = float

Full name: Microsoft.FSharp.Core.float<_>
static member GenericNumber.genericNumber : x:int32 * bigint -> BigInteger

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
type bigint = BigInteger

Full name: Microsoft.FSharp.Core.bigint
static member GenericNumber.genericNumber : x:int32 * decimal -> decimal

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
Multiple items
val decimal : value:'T -> decimal (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.decimal

--------------------
type decimal = System.Decimal

Full name: Microsoft.FSharp.Core.decimal

--------------------
type decimal<'Measure> = decimal

Full name: Microsoft.FSharp.Core.decimal<_>
static member GenericNumber.genericNumber : x:int32 * Complex -> Complex

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
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

Full name: System.Numerics.Complex

--------------------
Complex()
Complex(real: float, imaginary: float) : unit
Complex.op_Implicit(value: float) : Complex
Complex.op_Implicit(value: float32) : Complex
Complex.op_Implicit(value: byte) : Complex
Complex.op_Implicit(value: sbyte) : Complex
Complex.op_Implicit(value: uint64) : Complex
Complex.op_Implicit(value: uint32) : Complex
Complex.op_Implicit(value: uint16) : Complex
Complex.op_Implicit(value: int64) : Complex
Complex.op_Implicit(value: int) : Complex
Complex.op_Implicit(value: int16) : Complex
static member GenericNumber.genericNumber : x:int64 * int64 -> int64

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
val x : int64
static member GenericNumber.genericNumber : x:int64 * uint64 -> uint64

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
static member GenericNumber.genericNumber : x:int64 * float32 -> float32

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
static member GenericNumber.genericNumber : x:int64 * float -> float

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
static member GenericNumber.genericNumber : x:int64 * bigint -> BigInteger

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
static member GenericNumber.genericNumber : x:int64 * decimal -> decimal

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
static member GenericNumber.genericNumber : x:int64 * Complex -> Complex

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
static member GenericNumber.genericNumber : x:string * float32 -> float32

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
val x : string
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = System.String

Full name: Microsoft.FSharp.Core.string
static member GenericNumber.genericNumber : x:string * float -> float

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
static member GenericNumber.genericNumber : x:string * bigint -> BigInteger

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
BigInteger.Parse(value: string) : BigInteger
BigInteger.Parse(value: string, provider: System.IFormatProvider) : BigInteger
BigInteger.Parse(value: string, style: System.Globalization.NumberStyles) : BigInteger
BigInteger.Parse(value: string, style: System.Globalization.NumberStyles, provider: System.IFormatProvider) : BigInteger
static member GenericNumber.genericNumber : x:string * decimal -> decimal

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
static member GenericNumber.genericNumber : x:string * Complex -> Complex

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
static member GenericNumber.genericNumber : x:int32 * Complex32 -> Complex32

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
Multiple items
type Complex32 =
  struct
    new : real:float32 * imaginary:float32 -> Complex32
    member CommonLogarithm : unit -> Complex32
    member Conjugate : unit -> Complex32
    member CubicRoots : unit -> Tuple<Complex32, Complex32, Complex32>
    member Equals : other:Complex32 -> bool + 1 overload
    member Exponential : unit -> Complex32
    member GetHashCode : unit -> int
    member Imaginary : float32
    member IsImaginaryOne : unit -> bool
    member IsInfinity : unit -> bool
    ...
  end

Full name: MathNet.Numerics.Complex32

--------------------
Complex32()
Complex32(real: float32, imaginary: float32) : unit
Complex32.op_Implicit(value: float32) : Complex32
Complex32.op_Implicit(value: uint64) : Complex32
Complex32.op_Implicit(value: uint32) : Complex32
Complex32.op_Implicit(value: int64) : Complex32
Complex32.op_Implicit(value: BigInteger) : Complex32
Complex32.op_Implicit(value: int) : Complex32
Complex32.op_Implicit(value: uint16) : Complex32
Complex32.op_Implicit(value: sbyte) : Complex32
Complex32.op_Implicit(value: int16) : Complex32
Complex32.op_Implicit(value: byte) : Complex32
static member GenericNumber.genericNumber : x:int32 * bignum -> BigRational

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
type bignum = BigRational

Full name: MathNet.Numerics.bignum
static member BigRational.FromInt : int -> BigRational
static member GenericNumber.genericNumber : x:int64 * Complex32 -> Complex32

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
static member GenericNumber.genericNumber : x:int64 * bignum -> BigRational

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
static member BigRational.FromBigInt : BigInteger -> BigRational
static member GenericNumber.genericNumber : x:string * Complex32 -> Complex32

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
static member GenericNumber.genericNumber : x:string * bignum -> BigRational

Full name: Script.NumericLiteralG.GenericNumber.genericNumber
val instance : a:'a * b:'b * c:'c -> 'c (requires member genericNumber)

Full name: Script.NumericLiteralG.instance
val a : 'a (requires member genericNumber)
val b : 'b (requires member genericNumber)
val c : 'c (requires member genericNumber)
val genericNumber : num:'a -> 'b (requires member genericNumber)

Full name: Script.NumericLiteralG.genericNumber
val num : 'a (requires member genericNumber)
module Unchecked

from Microsoft.FSharp.Core.Operators
val defaultof<'T> : 'T

Full name: Microsoft.FSharp.Core.Operators.Unchecked.defaultof
val FromZero : unit -> 'a (requires member get_Zero)

Full name: Script.NumericLiteralG.FromZero
module LanguagePrimitives

from Microsoft.FSharp.Core
val GenericZero<'T (requires member get_Zero)> : 'T (requires member get_Zero)

Full name: Microsoft.FSharp.Core.LanguagePrimitives.GenericZero
val FromOne : unit -> 'a (requires member get_One)

Full name: Script.NumericLiteralG.FromOne
val GenericOne<'T (requires member get_One)> : 'T (requires member get_One)

Full name: Microsoft.FSharp.Core.LanguagePrimitives.GenericOne
val FromInt32 : n:'a -> 'b (requires member genericNumber)

Full name: Script.NumericLiteralG.FromInt32
val n : 'a (requires member genericNumber)
val FromInt64 : n:'a -> 'b (requires member genericNumber)

Full name: Script.NumericLiteralG.FromInt64
val FromString : n:'a -> 'b (requires member genericNumber)

Full name: Script.NumericLiteralG.FromString

More information

Link:http://fssnip.net/mv
Posted:3 years ago
Author:Daniel Fabian (@iceypoi)
Tags: math , numerics , generics , type classes