F#: Destructuring bind with a discriminated union

你离开我真会死。 提交于 2019-12-12 10:36:51

问题


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
  • http://ideone.com/cS9bK0

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
  • http://ideone.com/7qL9mH

Output:

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

Perfect.


回答1:


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.



来源:https://stackoverflow.com/questions/36234637/f-destructuring-bind-with-a-discriminated-union

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!