1
votes

I have some nested Discriminated Unions

type Job = Sniff | Guard
type Dog = Chihuahua | GermanShepherd of Job

Here's a function that takes a Dog and returns a string.

let dogPrinter d =
    match d with
    | Chihuahua -> ""
    | GermanShepherd g ->
        match g with
        | Sniff -> ""
        | Guard -> ""

I can convert the first match to the function syntax:

let dogPrinter = function
    | Chihuahua -> ""
    | GermanShepherd g ->
        match g with
        | Sniff -> ""
        | Guard -> ""

How can I convert the second match to function?

3
This seems like an XY problem. Why do you want to do this? It's perfectly readable as-is. You could use nested patterns to avoid the second match though. - glennsl
Why? Just wondering how. What do you mean by nested patterns? Could you post an answer? - Brett Rowberry

3 Answers

5
votes

The idiomatic way of avoiding nested matches in scenarios like this is to use nested patterns:

let dogPrinter = function
    | Chihuahua -> ""
    | GermanShepherd Sniff -> ""
    | GermanShepherd Guard -> ""

You can nest patterns as deeply as you need, just like you can nest expressions when creating the values.

1
votes

The only way I could think of, which I think might generally be the best approach, because it separates the concerns appropriately. However, I don't think this function keyword adds any value. I usually just stick with the match keyword.

let jobPrinter = function
  | Sniff -> ""
  | Guard -> ""

let dogPrinter = function
  | Chihuahua -> ""
  | GermanShepherd job -> job |> jobPrinter
1
votes

Although I think @glennsl answer is what you should consider doing here's an aswer to what OP asked for:

type Job = Sniff | Guard
type Dog = Chihuahua | GermanShepherd of Job

let dogPrinter = function
    | Chihuahua -> "Voff"
    | GermanShepherd g ->
      g |> (  function 
              | Sniff -> "Sniff"
              | Guard -> "Guard"
            )