F# - performing non-deterministic groupings on lists -


i’m working on problem know can solve c#. prove boss f# able solve in more succinct way. understanding of functional programming still immature.

the problem:

i’m working list of ‘trade’ classes. definition of class follows:

type trade(brokerid : string, productid : string, marketid : string, buysideid : string, tradedate : string, ruleid : int) = class      member this.brokerid = brokerid     member this.productid = productid     member this.marketid = marketid     member this.buysideid = buysideid     member this.tradedate = tradedate end 

i need able group trades , apply rule each of resulting groups of data.

however cannot guarantee grouping of data i.e. rule determining grouping potentially change every time program run - instance may have group by:

  • tradedate, brokerid
  • tradedate only
  • tradedate, brokerid, accountid

... , on.

once have distinct groups easy (i think) apply rule (such ‘is total tradeamount greater 10,000’).

any / pointers creating functional orientated solution problem welcome.

many thanks.

if understand problem correctly, want call seq.groupby function. problem don't quite know lambda function want pass argument when writing code, because function may vary depending on choice of keys should used grouping. here 1 relatively simple way this...

we'll create dictionary of functions gives function reading specified property of trade (this be, in principle, constructed automatically, easier write it):

let keyfunctions : idictionary<string, trade -> obj> =    dict [ "tradedate", (fun t -> box t.tradedate);            "brokerid", (fun t -> box t.brokerid);          "marketid", (fun t -> box t.marketid); ] 

now, if wanted use multiple keys, need way combine 2 functions give parts of key single function. can write combinator takes 2 functions , returns single 1 produces boxed tuple key:

let combine f1 f2 = (fun t -> box (f1 t, f2 t)) 

if have list of strings specifies keys, need pick function dictionary each of keys , combine them single function using combine:

let grouping = [ "tradedate"; "marketid" ] let func = grouping |> seq.map (fun n -> keyfunctions.[n]) |> seq.reduce combine 

and have function can used argument seq.groupby:

trades |> seq.groupby func 

there other ways in f#, think relatively simple approach convince boss :-). side-note, write same thing in c# 3.0, although bit uglier due more heavy syntax...

edit 1: nice thing approach don't need use reflection. runs compiled code, should pretty efficient. composed function calls several other functions (.net methods) , boxes returned values...

edit 2: regarding order - approach work (when comparing tuples, first elements compared first), i'm not entirely sure in order items aggregated when using seq.reduce, maybe example works other way round...


Comments

Popular posts from this blog

c++ - How do I get a multi line tooltip in MFC -

asp.net - In javascript how to find the height and width -

c# - DataTable to EnumerableRowCollection -