9
open System

let x = (1, 2)
let (p, q) = x
printfn "A %A" x
printfn "B %A %A" p q

let y = Some(1, 2)
try
  let None = y
  ()
with
  | ex -> printfn "C %A" ex
let Some(r, s) = y
printfn "D %A" y
// printfn "E %A %A" r s

When I uncomment the last line, the compiler rejects the code complaining

/home/rRiy1O/prog.fs(16,19): error FS0039: The value or constructor 'r' is not defined
/home/rRiy1O/prog.fs(16,21): error FS0039: The value or constructor 's' is not defined

Is it not allowed to use enumerations in destructuring let?

But first, even when I comment out the last line... what am I doing here? Here's the output:

A (1, 2)
B 1 2
D Some (1, 2)

Update

For the record, here's the fixed version:

open System

let x = (1, 2)
let (p, q) = x
printfn "A %A" x
printfn "B %A %A" p q

let y = Some(1, 2)
try
  let (None) = y
  ()
with
  | ex -> printfn "C %A" ex
let (Some(r, s)) = y
printfn "D %A" y
printfn "E %A %A" r s

Output:

A (1, 2)
B 1 2
C MatchFailureException ("/home/MBO542/prog.fs",10,6)
D Some (1, 2)
E 1 2

Perfect.

nodakai
  • 7,773
  • 3
  • 30
  • 60
  • 1
    Not directly related, but is the `let None = y` line creating a new value called None, perhaps? – Mark Pattison Mar 26 '16 at 11:25
  • @MarkPattison \\(^o^)/ – nodakai Mar 26 '16 at 11:28
  • In F# one should avoid redefining `None` or `Some` but it appears now that you are learning this one the hard way. Also with .NET and F# in particular avoid using `try ... catch` as it is time-wise expensive. If you need to catch errors/exceptions strongly consider using the [Option type](https://fsharpforfunandprofit.com/posts/the-option-type/) or for more advanced scenarios [Railway oriented programming](https://fsharpforfunandprofit.com/rop/) – Guy Coder Mar 26 '16 at 12:15
  • Could you change the title, I don't see an enumeration. – Guy Coder Mar 26 '16 at 12:19
  • @GuyCoder silly me, I updated the title. Discriminated unions are called enumerations in Rust on which I've been spending much time. By the way, `try...catch` was specifically for the non-exhaustive pattern match against `None` which yields an exception (I'm on mobile, can't find its exact name.) My intention was not redefining `None`. You seem to have misunderstood my intention behind this question. – nodakai Mar 26 '16 at 13:18
  • @GuyCoder You may post questions on them for yourself, this comment field is too narrow – nodakai Mar 26 '16 at 13:34

1 Answers1

11

The way you attempt to destructure y:

let Some(r, s) = y

You are actually defining a function named Some, with two arguments, r and s, passed in tupled form.

For correct destructuring, you need to add parentheses:

let (Some (r, s)) = y

Incidentally, same thing happens inside the try block: the line let None = y creates a new value named None and equal to y.

Fyodor Soikin
  • 78,590
  • 9
  • 125
  • 172
  • The fact that both of two cases for the `Option` enum compiled fine but worked against my intention beats me so hard. By the way, how did you gain such knowledge? By experience, or were there any descriptions in the language reference that I missed? – nodakai Mar 26 '16 at 11:43
  • 3
    Experience is the king, of course. Nothing makes one understand stuff like actually doing something with it. Explaining it to others also helps to improve your own understanding a lot, that's why I'm here :-). Besides that, I always recommend the excellent resource http://fsharpforfunandprofit.com, it's full of all kinds of great explanations. – Fyodor Soikin Mar 26 '16 at 11:45
  • 1
    Using VS (or presumably other IDEs) makes it pretty easy to see what's going on, by hovering over things to see their implied types. Or the interactive window will report the types immediately. – Mark Pattison Mar 26 '16 at 11:45
  • @MarkPattison True, if only I had VS on my Linux PC at home :-) – nodakai Mar 26 '16 at 12:04
  • 3
    On Linux, try Visual Studio Code + Ionide plugin for F# – Fyodor Soikin Mar 26 '16 at 12:05
  • @FyodorSoikin Got it, I'd have to spend more time in learning from excellent online resources – nodakai Mar 26 '16 at 12:05
  • @FyodorSoikin Thanks again for the tip, I was totally unaware of it. I'll give it a try – nodakai Mar 26 '16 at 12:08