"Subsetting" a dictionary in F# -


i'm beginner in f# , i'm trying write function subset dictionary given list, , return result.

i tried this, doesn't work.

let subset (dict:dictionary<'t,'u>) (sub_list:list<'t>) =     let z = dict.clear     sub_list |> list.filter (fun k -> dict.containskey k)              |> list.map (fun k -> (k, dict.trygetvalue k) )              |> list.iter (fun s -> z.add s)  |> list.iter (fun s -> z.add s);;   --------------------------------------^^^  stdin(597,39): error fs0039: field, constructor or member 'add' not defined 

perhaps there native function in f# ?

thanks

edit @theinnerlight answer below can educate me bit more, , tell me how should adapt function if want return original variable being modified ? (of course possible go call function, call temp variable, , reassign)

you have written:

let z = dict.clear 

z of type unit->unit yet calling z.add.

i suspect want write

let subset (dict:dictionary<'t,'u>) (sub_list:list<'t>) =     let z = dictionary<'t,'u>() // create new empty dictionary     sub_list |> list.filter (fun k -> dict.containskey k)              |> list.map (fun k -> (k, dict.[k]) )              |> list.iter (fun s -> z.add s)     z 

trygetvalue going return of type bool*'u in f#, suspect don't want if filtering containskey want directly dict.[k].

note dictionary mutable collection if call dict.clear(), wouldn't return new empty dictionary, mutate existing 1 clearing elements. immutable f# data structure used key-value relationships map, see https://msdn.microsoft.com/en-us/library/ee353880.aspx things can map.

here map version (this solution recommend):

let subset map sublist =     sublist      |> list.choose (fun k -> option.map (fun v -> k,v) (map.tryfind k map))     |> map.oflist 

edit (in response question edit modifying input variable):

it's possible update existing dictionary using destructive update operator <- on mutable variable.

option 1:

let mutable dict = dictionary<key,value>() // replace initial dictionary let lst = [] // list check against dict <- sublist dict lst 

likewise, first function changed perform side effect (removing unwanted elements).

option 2:

let subset (d : system.collections.generic.dictionary<'t,'u>) (sub_list : list<'t>) =     sub_list      |> list.filter (d.containskey >> not)     |> list.iter (d.remove >> ignore) 

for f# beginner don't recommend option 1 , really don't recommend option 2.

the functional approach favour immutable values, pure functions, etc. means better off thinking of functions defining data transformations rather defining list of instructions performed.

because f# multi-paradigm language, it's easy fall on imperative in stages gain learning new language if force adopt standard paradigm , idioms of language if idioms feel strange , uncomfortable begin with.

the immutable data structures map , list pretty efficient @ sharing data providing time complexity these go-to collections when working in f#.


Comments

Popular posts from this blog

ruby - Trying to change last to "x"s to 23 -

jquery - Clone last and append item to closest class -

c - Unrecognised emulation mode: elf_i386 on MinGW32 -