The best way would be to use a function combined with List.map
like so
let processFooList (foolist:Foo list ) = foolist |> List.map (function |Foo(t1,t2)->t1,t2)
質問
You know that to unwrap a value of a single union type you have to do this:
type Foo = Foo of int*string
let processFoo foo =
let (Foo (t1,t2)) = foo
printfn "%A %A" t1 t2
but my question is: if there a way to do that for lists ?:
let processFooList (foolist:Foo list ) =
let ??? = foolist // how to get a int*string list
...
thanks.
解決
The best way would be to use a function combined with List.map
like so
let processFooList (foolist:Foo list ) = foolist |> List.map (function |Foo(t1,t2)->t1,t2)
他のヒント
There's no predefined active pattern for converting the list from Foo
to int * string
, but you could combine the Named Pattern §7.2 (deconstruct single case union) with the projection into your own single case Active Pattern §7.2.3.
let asTuple (Foo(t1, t2)) = t1, t2 // extract tuple from single Foo
let (|FooList|) = List.map asTuple // apply to list
Use as function argument:
let processFooList (FooList fooList) = // now you can extract tuples from Foo list
... // fooList is an (int * string) list
Use in let-binding:
let (FooList fooList) =
[ Foo(1, "a"); Foo(2, "b") ]
printfn "%A" fooList // prints [(1, "a"); (2, "b")]
Distilling/summarising/restating/reposting the other two answers, your cited line:
let ??? = foolist // how to get a int*string list
Can become:
let ``???`` = foolist |> List.map (function |Foo(x,y) -> x,y)
If you're writing a transformation, you can do the matching in the params having defined an Active Pattern using either of the following:
let (|FooList|) = List.map <| fun (Foo(t1, t2)) -> t1,t2
let (|FooList|) = List.map <| function |Foo(t1, t2) -> t1,t2
which can then be consumed as follows:
let processFooList (fooList:Foo list ) =
// do something with fooList