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
Post a Comment