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
setFshould be:so then you’d use it like:
and call your
scoreFieldthus: