2 people like it.

Generic Numeric Type Conversions

Function that converts numeric types using type inference. This is meant to complement the generic number literal G in helping to write generic numeric code. The implementation is similar to the generic number literal snippet. See http://fssnip.net/mv/

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
open LanguagePrimitives

type NumericConversions = NumericConversions with
  // Add more conversions below as you see fit.
  static member inline convert(x : int, _ : int) = int x
  static member inline convert(x : int, _ : float) = float x
  static member inline convert(x : int, _ : float32) = float32 x
  static member inline convert(x : float, _ : int) = int x
  static member inline convert(x : float, _ : float) = float x
  static member inline convert(x : float, _ : float32) = float32 x
  static member inline convert(x : float32, _ : int) = int x
  static member inline convert(x : float32, _ : float) = float x
  static member inline convert(x : float32, _ : float32) = float32 x

// (Note that tooltips may be messed up because the snippet site compiler reports some bogus error - I don't know why.)
let inline convertNumericInstance(a : ^a, b : ^b, c : ^c) = ((^a or ^b or ^c) : (static member convert : ^b * ^c -> ^c) (b, c))

/// This function complements the generic numeric literal G by providing generic conversions of numbers using type inference.
let inline G x = convertNumericInstance(NumericConversions, x, GenericZero)

/// Example: the (normalized) sinc function. It uses the conversion function G to adopt pi to the inferred type.
let inline sinc x = if x = GenericZero then GenericOne else let px = G System.Math.PI * x in sin(px) / px
module LanguagePrimitives

from Microsoft.FSharp.Core
Multiple items
union case NumericConversions.NumericConversions: NumericConversions

--------------------
type NumericConversions =
  | NumericConversions
  static member convert : x:int * int -> int
  static member convert : x:int * float -> float
  static member convert : x:int * float32 -> float32
  static member convert : x:float * int -> int
  static member convert : x:float * float -> float
  static member convert : x:float * float32 -> float32
  static member convert : x:float32 * int -> int
  static member convert : x:float32 * float -> float
  static member convert : x:float32 * float32 -> float32

Full name: Script.NumericConversions
static member NumericConversions.convert : x:int * int -> int

Full name: Script.NumericConversions.convert
val x : int
Multiple items
val int : value:'T -> int (requires member op_Explicit)

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

--------------------
type int = int32

Full name: Microsoft.FSharp.Core.int

--------------------
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>
static member NumericConversions.convert : x:int * float -> float

Full name: Script.NumericConversions.convert
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 NumericConversions.convert : x:int * float32 -> float32

Full name: Script.NumericConversions.convert
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 NumericConversions.convert : x:float * int -> int

Full name: Script.NumericConversions.convert
val x : float
static member NumericConversions.convert : x:float * float -> float

Full name: Script.NumericConversions.convert
static member NumericConversions.convert : x:float * float32 -> float32

Full name: Script.NumericConversions.convert
static member NumericConversions.convert : x:float32 * int -> int

Full name: Script.NumericConversions.convert
val x : float32
static member NumericConversions.convert : x:float32 * float -> float

Full name: Script.NumericConversions.convert
static member NumericConversions.convert : x:float32 * float32 -> float32

Full name: Script.NumericConversions.convert
val convertNumericInstance : a:'a * b:'b * c:'c -> 'c (requires member convert)

Full name: Script.convertNumericInstance
val a : 'a (requires member convert)
val b : 'b (requires member convert)
val c : 'c (requires member convert)
val G : x:'a -> 'b (requires member convert and member get_Zero)

Full name: Script.G


 This function complements the generic numeric literal G by providing generic conversions of numbers using type inference.
val x : 'a (requires member convert and member get_Zero)
val GenericZero<'T (requires member get_Zero)> : 'T (requires member get_Zero)

Full name: Microsoft.FSharp.Core.LanguagePrimitives.GenericZero
val sinc : x:'a -> 'd (requires member get_Zero and equality and member ( * ) and member get_Zero and member convert and member ( / ) and member Sin and member get_One)

Full name: Script.sinc


 Example: the (normalized) sinc function. It uses the conversion function G to adopt pi to the inferred type.
val x : 'a (requires member get_Zero and equality and member ( * ) and member get_Zero and member convert and member ( / ) and member Sin and member get_One)
val GenericOne<'T (requires member get_One)> : 'T (requires member get_One)

Full name: Microsoft.FSharp.Core.LanguagePrimitives.GenericOne
val px : 'c (requires member ( / ) and member Sin and member get_Zero and member convert and member ( * ) and member get_Zero and equality and member get_One)
namespace System
type Math =
  static val PI : float
  static val E : float
  static member Abs : value:sbyte -> sbyte + 6 overloads
  static member Acos : d:float -> float
  static member Asin : d:float -> float
  static member Atan : d:float -> float
  static member Atan2 : y:float * x:float -> float
  static member BigMul : a:int * b:int -> int64
  static member Ceiling : d:decimal -> decimal + 1 overload
  static member Cos : d:float -> float
  ...

Full name: System.Math
field System.Math.PI = 3.14159265359
val sin : value:'T -> 'T (requires member Sin)

Full name: Microsoft.FSharp.Core.Operators.sin
Raw view Test code New version

More information

Link:http://fssnip.net/st
Posted:9 years ago
Author:Sami Perttu
Tags: math , numerics , generics , type classes