0 people like it.

Fun with polynoms and inline

for all those wanting to see the (rather unknown) statical interference of type-parameters (in contrast to generic type parameters) in action. I demonstrated this by having som e fun with basic algebra and polynoms

Definition of a polynom

1: 
2: 
3: 
/// a Polynom is just a list of coefficients
/// mind that [a; b; c] correspondents to a*X^0 + b*X^1 + c*X^2
type Polynom<'a> = 'a list

Polynom homomorphisms

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
module Polynoms =
    
    /// use the power of inline and List.fold to implement a simple polynom eval function for generic polynoms
    let inline Eval (p : 'a Polynom) (v : 'b) =
        p |> List.fold (fun (x, sum) coeff -> 
                        (x*v), (sum + x*coeff)) 
                       (Microsoft.FSharp.Core.LanguagePrimitives.GenericOne, Microsoft.FSharp.Core.LanguagePrimitives.GenericZero)
          |> snd

    /// returns a the polynom-function for a polynom
    let inline CreatePolynomFunction p = Eval p

    /// returns a function that evaluates every given Polynom p at the point v
    let inline EvalHom v = fun p -> Eval p v

Some samples with float

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
module Samples =
    
    // define a simple Polynom
    let P : Polynom<_> = [4.0; 1.0; 2.0] // 2.0*X^2 + X + 4.0

    // create the polynomfunction and get some values
    let p = Polynoms.CreatePolynomFunction P
    let c0 = p 0.0
    let c1 = p 1.0
    let c2 = p 2.0

    // play with the EvalHom
    // check the "get the coefficient for X^0"-Hom
    let c0hom = Polynoms.EvalHom 0.0
    let c0' = c0hom P
    System.Diagnostics.Debug.Assert((c0 = c0'))

    // get the sum of all coefficients (nice trick - evaluate at 1)
    let coeffSum = Polynoms.EvalHom 1.0
    let c1' = coeffSum P
    System.Diagnostics.Debug.Assert((c1 = c1'))
type 'T list = List<'T>

Full name: Microsoft.FSharp.Collections.list<_>
val Eval : p:Polynom<'a> -> v:'b -> 'c (requires member ( * ) and member ( * ) and member get_One and member ( + ) and member get_Zero)

Full name: Script.Polynoms.Eval


 use the power of inline and List.fold to implement a simple polynom eval function for generic polynoms
val p : Polynom<'a> (requires member ( * ) and member ( * ) and member get_One and member ( + ) and member get_Zero)
type Polynom<'a> = 'a list

Full name: Script.Polynom<_>


 a Polynom is just a list of coefficients
 mind that [a; b; c] correspondents to a*X^0 + b*X^1 + c*X^2
val v : 'b (requires member ( * ) and member ( * ) and member get_One and member ( + ) and member get_Zero)
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
  | ( [] )
  | ( :: ) of Head: 'T * Tail: 'T list
  interface IEnumerable
  interface IEnumerable<'T>
  member Head : 'T
  member IsEmpty : bool
  member Item : index:int -> 'T with get
  member Length : int
  member Tail : 'T list
  static member Cons : head:'T * tail:'T list -> 'T list
  static member Empty : 'T list

Full name: Microsoft.FSharp.Collections.List<_>
val fold : folder:('State -> 'T -> 'State) -> state:'State -> list:'T list -> 'State

Full name: Microsoft.FSharp.Collections.List.fold
val x : 'a (requires member ( * ) and member ( * ) and member get_One and member ( + ) and member get_Zero)
val sum : 'c (requires member ( + ) and member get_Zero and member ( * ) and member ( * ) and member get_One)
val coeff : 'a (requires member ( * ) and member ( * ) and member get_One and member ( + ) and member get_Zero)
namespace Microsoft
namespace Microsoft.FSharp
namespace Microsoft.FSharp.Core
module LanguagePrimitives

from Microsoft.FSharp.Core
val GenericOne<'T (requires member get_One)> : 'T (requires member get_One)

Full name: Microsoft.FSharp.Core.LanguagePrimitives.GenericOne
val GenericZero<'T (requires member get_Zero)> : 'T (requires member get_Zero)

Full name: Microsoft.FSharp.Core.LanguagePrimitives.GenericZero
val snd : tuple:('T1 * 'T2) -> 'T2

Full name: Microsoft.FSharp.Core.Operators.snd
val CreatePolynomFunction : p:Polynom<'a> -> ('c -> 'e) (requires member ( * ) and member ( * ) and member get_One and member ( + ) and member get_Zero)

Full name: Script.Polynoms.CreatePolynomFunction


 returns a the polynom-function for a polynom
val EvalHom : v:'a -> p:Polynom<'c> -> 'e (requires member ( * ) and member ( * ) and member get_One and member ( + ) and member get_Zero)

Full name: Script.Polynoms.EvalHom


 returns a function that evaluates every given Polynom p at the point v
val v : 'a (requires member ( * ) and member ( * ) and member get_One and member ( + ) and member get_Zero)
val p : Polynom<'c> (requires member ( * ) and member ( * ) and member get_One and member ( + ) and member get_Zero)
module Samples

from Script
val P : Polynom<float>

Full name: Script.Samples.P
val p : (float -> float)

Full name: Script.Samples.p
module Polynoms

from Script
val c0 : float

Full name: Script.Samples.c0
val c1 : float

Full name: Script.Samples.c1
val c2 : float

Full name: Script.Samples.c2
val c0hom : (Polynom<float> -> float)

Full name: Script.Samples.c0hom
val c0' : float

Full name: Script.Samples.c0'
namespace System
namespace System.Diagnostics
type Debug =
  static member Assert : condition:bool -> unit + 3 overloads
  static member AutoFlush : bool with get, set
  static member Close : unit -> unit
  static member Fail : message:string -> unit + 1 overload
  static member Flush : unit -> unit
  static member Indent : unit -> unit
  static member IndentLevel : int with get, set
  static member IndentSize : int with get, set
  static member Listeners : TraceListenerCollection
  static member Print : message:string -> unit + 1 overload
  ...

Full name: System.Diagnostics.Debug
System.Diagnostics.Debug.Assert(condition: bool) : unit
System.Diagnostics.Debug.Assert(condition: bool, message: string) : unit
System.Diagnostics.Debug.Assert(condition: bool, message: string, detailMessage: string) : unit
System.Diagnostics.Debug.Assert(condition: bool, message: string, detailMessageFormat: string, [<System.ParamArray>] args: obj []) : unit
val coeffSum : (Polynom<float> -> float)

Full name: Script.Samples.coeffSum
val c1' : float

Full name: Script.Samples.c1'
Next Version Raw view Test code New version

More information

Link:http://fssnip.net/4r
Posted:13 years ago
Author:Carsten König
Tags: inline , polynom , statical resolved type parameters