Skip to content

Instantly share code, notes, and snippets.

@caindy
Created August 3, 2014 18:40
Show Gist options
  • Save caindy/778c6e116a495d6ef394 to your computer and use it in GitHub Desktop.
Save caindy/778c6e116a495d6ef394 to your computer and use it in GitHub Desktop.
highlighting the expressiveness of total single-case active pattern
open System.Numerics
let (|Rect|) (x: Complex) = (x.Real, x.Imaginary)
let (|Polar|) (x: Complex) = (x.Magnitude, x.Phase)
//conversion functions easily expressed in terms of active patterns
let toRect = function | Rect(r, i) -> (r, i)
let toPolar = function | Polar(m, p) -> (m, p)
//following two functions are equivalent, but the former reads better IMO
let multp a b =
match a, b with
| Polar(m, p), Polar(n, q) -> Complex.FromPolarCoordinates(m*n, (p+q))
let mult a b =
match toPolar(a), toPolar(b) with
| (m, p), (n, q) -> Complex.FromPolarCoordinates(m*n, (p+q))
// try expressing this idea with the functions
let addOrMult a b =
match a, b with
| Rect(ar,ai), Rect(br, bi) when ar > br -> Complex(ar+br, ai+bi)
| Polar(m, p), Polar(n, q) -> Complex.FromPolarCoordinates(m*n, (p+q))
@caindy
Copy link
Author

caindy commented Aug 3, 2014

This discussion by Richard Dalton is very thorough-going, and ends with an example much like #L21 saying, "it still feels a bit contrived. If this kind of situation does arise, I think it may be a bit of an edge case rather than a common situation. Maybe I’m wrong."

My view is that having the single-case total active pattern is useful often enough that it is worth writing when you need the conversion function, since the latter is easy to write with it. As his last example elucidates, when you have the "same data with many views" (@dsyme et al. in Expert F#), you can write very concise match expressions over that data with active patterns.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment