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?

MiloDC
  • 2,373
  • 1
  • 16
  • 25
  • 1
    That would be nice. Shame it's not supported. – TheQuickBrownFox Nov 09 '20 at 10:47
  • While this could be suggested in https://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. – Charles Roddie Nov 16 '20 at 12:20

1 Answers1

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
Gus
  • 25,839
  • 2
  • 51
  • 76
  • 1
    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. – MiloDC Nov 09 '20 at 22:56
  • 1
    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. – Gus Nov 10 '20 at 06:46