Given a type (Candidate) which has muiltiple fields one may score (here one concrete example with _scoreXXX) and calculate the total percentage score:
type ScorableCandidate() =
let mutable _scoreXXX: int = 0 ;
let mutable _percentXXX: float = 0. ;
member this.scoreXXX
with get() = _scoreXXX
and set(v) =
_scoreXXX<- v
propertyChanged.Trigger(this, new PropertyChangedEventArgs("scoreXXX"))
member this.percentXXX
with get() = _percentXXX
and set(v) =
_percentXXX <- v
propertyChanged.Trigger(this, new PropertyChangedEventArgs("percentXXX"))
I would like to absctract the calculation of the percentages so I don't need to redefine the function everytime. Unfortunately I am lost on how to do this with member functions. The template of the code I am abstracting looks is:
let scoreXXXs () =
let totalXXXScore = List.fold (fun acc (candidate: ScorableCandidate) -> acc + candidate.scoreXXXs) 0 brokers
let score (candidate: ScorableCandidate) =
candidate.percentXXXs <- (float candidate.scoreXXXs) / float totalXXXScore * 100.
if totalXXXScore > 0 then
List.iter score <| brokers
I guess I would like to be able to define the function as "score" and pass in the aapropriate member accessors. Such that i could write
score XXX // where xxx is some property in the class that needs to be scored
score YYY // where yyy is some property in the class that needs to be scored
One thought I had was passing in functions to get access, and that is easy enough to do for the getter but I can't seem to figure out the setter. I realize I could defer to reflection for this - but I feel that might not be the best (f#) way... AT this point I am at:
let scoreField (accessF : (ScorableCandidate -> int)) (setF : (float -> unit)) =
let totalScore = List.fold (fun acc (candidate: ScorableCandidate) -> acc + accessF candidate) 0 brokers
let score (candidate: ScorableCandidate) =
setF <| (accessF candidate |> float) / float totalScore * 100.
if totalScore > 0 then
List.iter score <| brokers
scoreField (fun c -> c.scoreXXX) (fun f -> ())
But I don't know how (or if it is possible) to represent the setter as a lambda function on the type (where maybe I can pass the instace as paraneter to lambda function and invoke it somehow).
Thoughts? Thanks ahead.
Update Found this approach (thoughts):
http://laurent.le-brun.eu/site/index.php/2009/10/17/52-dynamic-lookup-operator-aka-duck-typing-in-fsharp
You're on the right track, but your settor is missing the object you're going to set the field on. So the type of setF should be:
setF : (ScorableCandidate -> float -> unit)
so then you'd use it like:
let score (candidate: ScorableCandidate) =
(setF candidate) <| (accessF candidate |> float) / float totalScore * 100.
and call your scoreField thus:
scoreField (fun c -> c.scoreXXX) (fun c f -> c.percentXXX <- f)
So, if I understand it correctly, you need to store several scores (for various different things) in a single candidate and then perform calculations over these scores.
In that case, I would consider making Score a separate type that would be used by the candidate - you can then easily add multiple scores. If you need to expose score & percent as direct properties of candidate & notify using IPropertyChange, then you should be able to write something like this:
/// Takes a name of this score item (e.g. XXX) and a
/// function to trigger the property changed event
type Score(name:string, triggerChanged) =
let mutable score = 0
let mutable percent = 0.0
member x.Score
with get() = score
and set(v) =
score <- v
triggerChanged("Score" + name)
member x.Percent
with get() = percent
and set(v) =
percent <- v
triggerChanged("Percent" + name)
Now you can simply use the Score object as many times you need in the candidate (because we also want to expose direct properties, there is some boilerplate, but it should be reasonable amount):
type ScorableCandidate() as this =
// Create trigger function & pass it to Score objects
let trigger n = propertyChanged.Trigger(this, n)
let infoXxx = new Score("Xxx", trigger)
member this.InfoXxx = scoreXxx // Exposes the whole Score object
member this.ScoreXxx = scoreXxx.Score // & individual...
member this.PercentXxx = scoreXxx.Percent // ...properties
Now, your parameterized function can simply take a function that takes ScorableCandidate and returns a Score object:
let scores f =
let totalScore = List.fold (fun acc (candidate: ScorableCandidate) ->
let so = f candidate // Get 'Score' object
acc + so.Score) 0 brokers
let score (candidate: ScorableCandidate) =
let so = f candidate // Get 'Score' object
so.Percent <- (float so.Score) / float totalScore * 100.0
if totalScore > 0 then
List.iter score <| brokers
Example call would be simply:
scores (fun (c:ScorableCandidate) -> c.InfoXxx)
This makes the call to the scores function as easy as it can get and it is also scalable solution that makes it easy to add other calculations to the Score object. The disadvantage (e.g. when compared with Pavel's straightforward solution) is that there is a bit more work with designing the Score type (however, declaring new scores in ScorableCandidate is then arguably easier if you only need to expose readable property directly in the class - which I think should be enough).
To make the API simpler, you might want to consider one of the following options:
Use reflection. Then you could do scoreField "XXX", and your method could explicitly translate "XXX" into MethodInfos for your get_scoreXXX and set_percentXXX methods. This has the disadvantage that it doesn't check the method names at compile time and it has the performance penalty that comes along with reflection.
Use quotations. Then you could do scoreField <# fun c -> c.scoreXXX, c.percentXXX #>. This would otherwise work similarly to the reflection example, except that you'd have a bit more compile-time checking.
Create a type which represents score/percent combinations, and create properties of that type rather than separate properties for each. Your ScorePercent class could have getters and setters for the score and percent (and raise its own change notifications). Then, you could do scoreField (fun c -> c.XXX), where the XXX member is of type ScorePercent.
Related
I read the following type definition. What does it do?
type StreamCell<'a> =
| Nill
| Cons of 'a * Stream<'a>
and Stream<'a> = Lazy<StreamCell<'a>>
I tried to define the value with the type.
let x = Lazy(1::2::Nill) // Type is Lazy<list<int>>
let y = Lazy(Nill::1) // Lazy<StreamCell<obj>>
I thought the type of x and y should be StreamCell?
The and in F# exists to define recursive types. In most other languages there exists no order. Once you define a class, function and so on. You can access it. But in F# order is important. You only can access thinks that are already defined.
Because of this, usually it would not be possible to define recursive types, or in generall circular types. What i think is a good idea. But sometimes, you want this, and in this case, you must define the types that should be recursive with an and.
A simple example would be
type A = A of B
type B = B of A
and this will fail. Because when you define A, there is no B. So B must be defined before A. But you cannot define B before A because it depends on A.
So instead of using type you use and instead.
type A = A of B
and B = B of A
You cannot create a value of this type because it would be infinite, but it's only for understanding the problem. Next, your example is not the best, because.
and Stream<'a> = Lazy<StreamCell<'a>>
is only a Type Alias. Here you define Stream<'a> as an alias to Lazy<StreamCell<'a>>. But the compiler will usually not use Stream<'a>. This only helps if you would write the type manually in your function definitions. Your definition could also be.
type StreamCell<'a> =
| Nill
| Cons of 'a * Lazy<StreamCell<'a>>
In your example
let x = Lazy(1::2::Nill)
You use :: and this IS NOT the Cons you define with your stream. You will use the cons operator that is defined with F#, and that is the built-in list. This is the reason why you see Lazy<List<int>> as a type.
If you want to define your stream with two values you need to write.
let x = Cons(1,lazy Cons(2, lazy Nill))
As a general note i would rename Cons to Next or something else. To avoid confusion and create helper function to create Nill and Next values.
Addition
and can also be used to change the Order of definition, and make it more obvious, which types belong together.
type Person = {
Name: string
Sex: Sex
}
and Sex =
| Male
| Female
let person = { Name="David"; Sex=Male }
Example
Here is a full-blown example how i would do a Stream type on what you provided.
type Stream<'a> =
| Nill
| Next of 'a * Lazy<Stream<'a>>
let nill = Nill
let next h t = Next(h,t)
let rec unfold gen state =
match gen state with
| None -> Nill
| Some(x,state) -> next x (lazy unfold gen state)
let rec fold f acc xs =
match xs with
| Nill -> acc
| Next(h,t) -> fold f (f acc h) (t.Force())
let rec rev stream =
fold (fun acc x -> next x (lazy acc)) nill stream
let toList stream =
fold (fun acc x -> x::acc ) [] (rev stream)
let rec take x stream =
if x > 0 then
match stream with
| Nill -> Nill
| Next(h,t) -> next h (lazy take (x-1) (t.Force()))
else
Nill
let fromTo start stop =
unfold (fun acc -> if acc<stop then Some(acc,acc+1) else None) start
let x = next 1 (lazy next 2 (lazy next 3 (lazy nill)))
let y = next 1.0 (lazy next 2.0 (lazy next 3.0 (lazy nill)))
printfn "%A" (toList (take 2 x))
printfn "%A" (toList (take 2 y))
printfn "%A" (toList (take 2 (fromTo 1 100)))
printfn "%A" (toList (take 5 (fromTo 1 1_000_000_000)))
I am looking for an idiomatic approach to programming filters in F#. For clarity, I refer to a filter as a function that uses a series of measurements over time and produces evolving estimates. This implies that the function be able to maintain state. For example, in Python one could use coroutines to maintain state in a very clean way.
What I'm looking for is an idiomatic approach to programming filters in F#. Given that my mind is thoroughly polluted with OOP and procedural principles, naturally I came up with classes to express them. Is there a more idiomatic approach to filtering in F#, one that could perhaps open up other benefits of the functional paradigm?
open System
open MathNet.Numerics.LinearAlgebra
open MathNet.Numerics.Random
open MathNet.Numerics.Distributions
open MathNet.Numerics.Statistics
open FSharp.Charting
type ScalarKalman (A : float, H : float, Q : float, R : float) = class
let mutable A = A
let mutable H = H
let mutable Q = Q
let mutable R = R
let mutable p = 0.
let mutable x = 0.
let mutable k = 0.
let mutable result = 0.
member this.X
with get() = x
and set(value) = x <- value
member this.P
with get() = p
and set(value) = p <- value
member this.K
with get() = k
and set(value) = k <- value
member this.update(newVal : float) =
let xp = A * this.X
let Pp = A * this.P * A + Q
this.K <- Pp * H / (H * Pp * H + R)
this.X <- xp + this.K * (newVal - H * xp)
this.P <- Pp - this.K * H * Pp
end
let n = 100
let obsv = [|for i in 0 .. n do yield 0.|]
let smv = [|for i in 0 .. n do yield 0.|]
let kal = new ScalarKalman(1., 1., 0., 5.)
kal.P <- 4.
kal.X <- 6.
for i in 0 .. n do
obsv.[i] <- Normal.Sample(10., 5.)
kal.update(obsv.[i])
smv.[i] <- kal.X
Chart.Combine([obsv |> Chart.FastLine
smv |> Chart.FastLine]) |> Chart.Show
In your case, the terms "functional" and "F# idiomatic" would consist of two things: immutable data and separation of data from code.
Immutable data: you would have one data structure representing the filter parameters (i.e. A, H, Q, and R), and another structure representing the filter's current state (i.e. X, K, and P). Both immutable. Instead of mutating the state, you would produce a new one.
Separation of data from code: the filter itself would consist of a single function that takes parameters, current state, next observation value, and produces next state. This next state will then be fed back into the function along with the next observation value, thus producing next+1 state, and so on. The parameters always stay constant, so they can be passed in just once, using partial application (see below).
Once you have such function, you can "apply" it to the list of observations as a "rolling projection", - as described above, - taking each observation and feeding it into the function along with the last state, producing the next state. This "rolling projection" operation is a very common thing in functional programming, and is usually called scan. F# does provide implementations of scan for all standard collections - list, seq, etc.
As a result of scan, you will have a list of filter's successive states. Now all that's left to do is to fish the X value out of each state.
Here is the complete solution:
module ScalarKalman =
type Parameters = { A : float; H : float; Q : float; R : float }
type State = { K: float; X: float; P: float }
let initState (s: State) = s
let getX s = s.X
let update parms state newVal =
let xp = parms.A * state.X
let Pp = parms.A * state.P * parms.A + parms.Q
let newK = Pp * parms.H / (parms.H * Pp * parms.H + parms.R)
{ K = newK
X = xp + newK * (newVal - parms.H * xp)
P = Pp - newK * parms.H * Pp }
let n = 100
let obsv = [for i in 0 .. n -> Normal.Sample(10., 5.)]
let kal = ScalarKalman.update { A = 1.; H = 1.; Q = 0.; R = 5. }
let initialState = ScalarKalman.initState { X = 6.; P = 4.; K = 0. }
let smv =
obsv
|> List.scan kal initialState
|> List.map ScalarKalman.getX
A note on design
Note the initState function declared in the module. This function may seem silly on the surface, but it has important meaning: it lets me specify state fields by name without opening the module, thus avoiding namespace pollution. Plus, the consuming code now looks more readable: it says what it does, no comments required.
Another common approach to this is to declare a "base" state in the module, which consuming code could then amend via the with syntax:
module ScalarKalman =
...
let zeroState = { K = 0.; X = 0.; P = 0. }
...
let initialState = { ScalarKalman.zeroState with X = 6.; P = 4. }
A note on collections
F# lists are fine on small amounts of data and small processing pipelines, but become expensive as these two dimensions grow. If you're working with a lot of streaming data, and/or if you're applying multiple filters in succession, you might be better off using lazy sequences - seq. To do so, simply replace List.scan and List.map with Seq.scan and Seq.map respectively. If you do, you will get a lazy sequence as the ultimate result, which you will then need to somehow consume - either convert it to a list, print it out, send it to the next component, or whatever your larger context implies.
While the code I have does what I need, I feel I am missing some coding technique to implement this kind of stuff in a more concise way.
The goal is to compose items and give them an Id value along the way.
Here the code which I feel can be simplified and improved in many ways. If only I knew, how...
type Foo = | A of int | B of int | C of int
let ids startvalue = Seq.initInfinite (fun i -> i + startvalue)
let makeA ids =
A(Seq.head ids), Seq.skip 1 ids
let makeB ids =
B(Seq.head ids), Seq.skip 1 ids
let makeC ids =
C(Seq.head ids), Seq.skip 1 ids
let config = [makeA; makeA; makeC; makeB]
let create (ids : seq<int>) (cfg : (seq<int> -> Foo * seq<int>) list) : Foo list * seq<int> =
let rec cre ids1 acc cl =
match cl with
| [] -> (acc,ids1)
| x::xs ->
let v,ids2 = x ids1
cre ids2 (acc # [v]) xs
cre ids [] cfg
let result : Foo list * seq<int> = create (ids 0) config
Which results in the very simple:
val result : Foo list * seq = ([A 0; A 1; C 2; B 3], )
Somehow I feel there should be an easier way to accomplish the same.
In fact, I know one way to make it simpler but this would involve mutable state and memoization (and would thusly be probably considered worse):
let idgen startvalue =
let v = ref startvalue
fun () ->
let result = !v
v := !v + 1
result
With the thusly received generator function I could get rid of all those tuples, at least and I could also get rid of create function and simply write:
let ids = idgen 0
let result =
[
A(ids())
A(ids())
C(ids())
B(ids())
]
But there should also exist a "functional" way to get it done more simply.
It seems that what you want is to take two sequences, one of functions, the other of arguments, and produce new sequence by applying functions to corresponding arguments, where in your particular case arguments are successive integer numbers and functions are union case constructors. Would that be a correct assessment?
If so, here's what I would do:
let create args funs =
Seq.zip args funs
|> Seq.map (fun (arg, fn) -> fn arg)
|> List.ofSeq
let result = create (ids 0) [A; A; C; B]
type Foo = | A of int | B of int | C of int
let ids startvalue = Seq.initInfinite (fun i -> i + startvalue)
let config = [A; A; C; B]
let create ids i cfg =
let ids' = ids i
let nextI = i + List.length cfg
(Seq.map2 id cfg ids'), nextI
let result, nextI = create ids 0 config
let result2, nextI2 = create ids nextI config
There are several considerations here:
A, B, and C are constructors of the type int -> Foo. You may directly use them as functions and eliminate repetitive wrapper functions;
Seq.map2 is able to process sequences of different length and ignore the remaining elements of the longer one;
id is a shortcut for fun f number -> f number, please use the longer one if you find id unclear
You may also refactor ids function into Seq.initInfinite id |> Seq.skip startvalue.
At the end, you may convert a sequence into a List if you really need.
Updated to receive an keep i and nextI.
As Fyodor pointed out in his answer, you really just want to apply your constructors to consecutive integers. You can use the built-in mapi for that, writing your entire program as:
type Foo = | A of int | B of int | C of int
let config = [A; A; B; C]
let create offset = List.mapi (fun i f -> f (offset + i))
create 78 config
// val it : Foo list = [A 78; A 79; B 80; C 81]
I'm new on F#, and can't see how extract the int value from:
let autoInc = FsCheck.Gen.choose(1,999)
The compiler say the type is Gen<int>, but can't get the int from it!. I need to convert it to decimal, and both types are not compatible.
From a consumer's point of view, you can use the Gen.sample combinator which, given a generator (e.g. Gen.choose), gives you back some example values.
The signature of Gen.sample is:
val sample : size:int -> n:int -> gn:Gen<'a> -> 'a list
(* `size` is the size of generated test data
`n` is the number of samples to be returned
`gn` is the generator (e.g. `Gen.choose` in this case) *)
You can ignore size because Gen.choose ignores it, as its distribution is uniform, and do something like:
let result = Gen.choose(1,999) |> Gen.sample 0 1 |> Seq.exactlyOne |> decimal
(* 0 is the `size` (gets ignored by Gen.choose)
1 is the number of samples to be returned *)
The result should be a value in the closed interval [1, 999], e.g. 897.
Hi to add to what Nikos already told you, this is how you can get an decimal between 1 and 999:
#r "FsCheck.dll"
open FsCheck
let decimalBetween1and999 : Gen<decimal> =
Arb.generate |> Gen.suchThat (fun d -> d >= 1.0m && d <= 999.0m)
let sample () =
decimalBetween1and999
|> Gen.sample 0 1
|> List.head
you can now just use sample () to get a random decimal back.
In case you just want integers between 1 and 999 but have those converted to decimal you can just do:
let decimalIntBetween1and999 : Gen<decimal> =
Gen.choose (1,999)
|> Gen.map decimal
let sampleInt () =
decimalIntBetween1and999
|> Gen.sample 0 1
|> List.head
what you probably really want to do instead
Is use this to write you some nice types and check properties like this (here using Xunit as a test-framework and the FsCheck.Xunit package:
open FsCheck
open FsCheck.Xunit
type DecTo999 = DecTo999 of decimal
type Generators =
static member DecTo999 =
{ new Arbitrary<DecTo999>() with
override __.Generator =
Arb.generate
|> Gen.suchThat (fun d -> d >= 1.0m && d <= 999.0m)
|> Gen.map DecTo999
}
[<Arbitrary(typeof<Generators>)>]
module Tests =
type Marker = class end
[<Property>]
let ``example property`` (DecTo999 d) =
d > 1.0m
Gen<'a> is a type that essentially abstracts a function int -> 'a (the actual type is a bit more complex, but let's ignore for now). This function is pure, i.e. when given the same int, you'll get the same instance of 'a back every time. The idea is that FsCheck generates a bunch of random ints, feeds them to the Gen function, out come random instances of the type 'a you're interested in, and feeds those to a test.
So you can't really get out the int. You have in your hands a function that given an int, generates another int.
Gen.sample as described in another answer essentially just feeds a sequence of random ints to the function and applies it to each, returning the results.
The fact that this function is pure is important because it guarantees reproducibility: if FsCheck finds a value for which a test fails, you can record the original int that was fed into the Gen function - rerunning the test with that seed is guaranteed to generate the same values, i.e. reproduce the bug.
I am currently porting some code from Java to F# that deals with multidimensional functions. It supports variable dimension, so in the original implementation each point is represented as an array of doubles. The critical function of the code is an optimisation routine, that basically generates a sequence of points based on some criteria, evaluates a given function at these points and looks for a maximum. This works for any dimension. The operations I need are:
check the dimension of a point
create a new point with the same dimension of a given point
set (in procedural or functional sense) a given coordinate of a point
In F# I could obviously also use arrays in the same way. I was wandering though if there is a better way. If the dimension was fixed in advance, the obvious choice would be to use tuples. Is it possible to use tuples in this dynamic setting though?
No, tuples will be fixed by dimension. Also note that .NET tuples are boxed. If you are operating on large collections of points with small dimension (such as arrays of 2d points), using structs may help.
If you really want to push the F#/.NET advantage over Java, have a look at generics. Writing code with generics allows to write code that works for any dimension, and use different representations for different dimensions (say structs for 1-3 dimensions, and vectors for larger dimensions):
let op<'T where 'T :> IVector> (x: 'T) =
...
This is only relevant though if you are willing to go a long way to get the absolutely best performance and generality. Most projects do not need that, stick with the simplest thing that works.
For the fun of it, here is an extended example of how to utilize generics and F# inlining:
open System.Numerics
type IVector<'T,'V> =
abstract member Item : int -> 'T with get
abstract member Length : int
abstract member Update : int * 'T -> 'V
let lift<'T,'V when 'V :> IVector<'T,'V>> f (v: 'V) : 'V =
if v.Length = 0 then v else
let mutable r = v.Update(0, f v.[0])
for i in 1 .. v.Length - 1 do
r <- r.Update(i, f v.[i])
r
let inline norm (v: IVector<_,_>) =
let sq i =
let x = v.[i]
x * x
Seq.sum (Seq.init v.Length sq)
let inline normalize (v: 'V) : 'V =
let n = norm v
lift (fun x -> x / n) v
[<Struct>]
type Vector2D<'T>(x: 'T, y: 'T) =
member this.X = x
member this.Y = y
interface IVector<'T,Vector2D<'T>> with
member this.Item
with get (i: int) =
match i with
| 0 -> x
| _ -> y
member this.Length = 2
member this.Update(i: int, v: 'T) =
match i with
| 0 -> Vector2D(v, y)
| _ -> Vector2D(x, v)
override this.ToString() =
System.String.Format("{0}, {1}", x, y)
[<Sealed>]
type Vector<'T>(x: 'T []) =
interface IVector<'T,Vector<'T>> with
member this.Item with get (i: int) = x.[i]
member this.Length = x.Length
member this.Update(i: int, v: 'T) =
let a = Array.copy x
a.[i] <- v
Vector(a)
override this.ToString() =
x
|> Seq.map (fun e -> e.ToString())
|> String.concat ", "
[<Struct>]
type C(c: Complex) =
member this.Complex = c
static member Zero = C(Complex(0., 0.))
static member ( + ) (a: C, b: C) = C(a.Complex + b.Complex)
static member ( * ) (a: C, b: C) = C(a.Complex * b.Complex)
static member ( / ) (a: C, b: C) = C(a.Complex / b.Complex)
override this.ToString() = string c
let v1 = Vector2D(10., 30.)
normalize v1
|> printfn "%O"
let v2 = Vector2D(C(Complex(1.25, 0.8)), C(Complex(0.5, -1.)))
normalize v2
|> printfn "%O"
let v3 = Vector([| 10.; 30.; 50.|])
normalize v3
|> printfn "%O"
Note that norm and normalize are fairly general, they cope with specialized 2D vectors and generalized N-dimensional vectors, and with different component types such as complex numbers (you can define your own). The use of generics and F# inlining ensure that while general, these algorithms perform well for the special cases, using compact representations. This is where F# and .NET generics shine compared to Java, where you are obliged to create specialized copies of your code to get decent performance.