f# - How to map a sequence of discriminated unions (where all items are of the same case) onto a sequence of items of the type of the case? -


i have following:

type union1 =     | case1 of string     | case2 of int  let union1s = seq { in 1..5 yield case2 } 

how change union1s sequence of type seq<int>?

something like:

let matchcase item =     match item     | case1 x -> x     | case2 x -> x  let case2s = seq.map matchcase union1s 

this attempt not work because matchcase can not return 2 different types.

the suggested answers have same problem (if understand correctly)

let matchcaseopt = function     | case1 x -> x     | case2 x -> x     | _ -> none  let case2s = seq.choose matchcaseopts unions1s 

the expression x expects expects type option string in match case2

i have solved particular use-case using du of sequences.

type union1s =     | case1s of seq<string>     | case2s of seq<int>     

you try following reflection-based, general purpose implementation:

open microsoft.fsharp.quotations open microsoft.fsharp.quotations.patterns open microsoft.fsharp.reflection  let filterunioncases (branch : expr<'t -> 'union>) (inputs : 'union list) =     let rec getunioncase (e : expr) =         match e         | newunioncase(unioncaseinfo,_) -> unioncaseinfo         | lambda(_, body) -> getunioncase body         | let(_, tupleget _, body) -> getunioncase body         | _ -> invalidarg "branch" "not union case constructor"      let getbranchcontents (uci : unioncaseinfo) (u : 'union) =         let uci', fields = fsharpvalue.getunionfields(u, typeof<'union>)         if uci = uci'             match fields             | [| field |] -> field :?> 't             | _ -> fsharpvalue.maketuple(fields, typeof<'t>) :?> 't             |>         else none      let uci = getunioncase branch     inputs |> list.choose (getbranchcontents uci)   filterunioncases <@ case1 @> [ case1 "string1" ; case2 2 ; case1 "string2" ] //  [ "string1" ; "string2" ] filterunioncases <@ case2 @> [ case1 "string1" ; case2 2 ; case1 "string2" ] //  [ 2 ] 

this should work in union cases contain multiple fields.


Comments

Popular posts from this blog

How to remove text and logo OR add Overflow on Android ActionBar using AppCompat on API 8? -

html - How to style widget with post count different than without post count -

url rewriting - How to redirect a http POST with urlrewritefilter -