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

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

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

javascript - storing input from prompt in array and displaying the array -