F# type test pattern matching: decomposing tuple objects
Asked Answered
F

1

1

Just curious why I can't do this:

let myFn (data : obj) =
    match data with
    | :? (string * string) as (s1, s2) -> sprintf "(%s, %s)" s1 s2 |> Some
    | :? (string * string * int) as (s1, s2, i) -> sprintf "(%s, %s, %d)" s1 s2 i |> Some
    | _ -> None

How come?

Freed answered 9/11, 2020 at 7:31 Comment(2)
That would be nice. Shame it's not supported.Postaxial
While this could be suggested in github.com/fsharp/fslang-suggestions , I think it's a bad idea as it would encourage people to write code like this. This code should be avoided because it requires use of obj and type matching. F# should be used in a type-safe way, and use of obj and downcasting detracts from that.Angelicangelica
F
2

See F# spec, section 7.3 "As patterns"

An as pattern is of the form pat as ident

Which means you need to use an identifier after as:

let myFn (data : obj) =
    match data with
    | :? (string * string)       as s1s2  -> let (s1, s2)    = s1s2  in sprintf "(%s, %s)" s1 s2 |> Some
    | :? (string * string * int) as s1s2i -> let (s1, s2, i) = s1s2i in sprintf "(%s, %s, %i)" s1 s2 i |> Some
    | _ -> None
Funches answered 9/11, 2020 at 9:7 Comment(2)
I know what the spec says. I was looking for a more technical explanation as to why deconstruction of a tuple after "as" isn't supported -- especially since most users would intuit this of the language.Freed
There's no technical limitation, other than the feature is not implemented. There are other places where de-construction is not supported, like in the "this" parameter of members, which is a place where you frequently want to deconstruct. All this can be added to the language after submitting a proposal, and getting approval for it.Funches

© 2022 - 2024 — McMap. All rights reserved.