Reputation: 12107
The code is getting a json string from a server and parses it into a jObject and then branches appropriately.
let j = JObject.Parse x
match x, j with
| _ when x = "pong" -> ()
| _ when j.ContainsKey "table" -> HandleTableMessages j x
| _ when j.ContainsKey "success" -> HandleSuccessMessages j
| _ when j.ContainsKey "error" -> HandleErrorMessages j
| _ when j.ContainsKey "info" -> j.SelectToken "info" |> string |> this.Print
| _, null -> this.Error ("malformed message: " + x)
| _ -> this.Error("unknown message type: " + x)
I think there is something a little bit heavy with the _ when
part and I am wondering if there a better use of the F# grammar to express this?
Upvotes: 1
Views: 85
Reputation: 947
It's a good sign that you realize this code is bad. It shows you may have better taste than most beginners. Using the simplest structure for a task is very important.
match x, j with
| _ when x = "pong" -> ()
...
First note that (x,j)
is unused, so this simplifies to:
match () with
| _ when x = "pong" -> ()
...
Then you can realize that matching on a unit is silly, and that you should have used a simpler statement:
if x = "pong" then ()
elif j.ContainsKey "table" then HandleTableMessages j x
...
else this.Error("unknown message type: " + x)
I have just noticed that elif
is not in the F# cheatsheet so I will try to get it added there as it's a basic keyword.
Upvotes: 4
Reputation: 1721
// Active Pattern
let (|Table|Success|Error|Info|Unknown|) (j: Newtonsoft.Json.Linq.JObject) =
if j.ContainsKey "table" then Table
elif j.ContainsKey "success" then Success
elif j.ContainsKey "error" then Error
elif j.ContainsKey "info" then Info
else Unknown
match x, j with
| "pong", _ -> ()
| _, Table -> HandleTableMessages j x
| _, Success -> HandleSuccessMessages j
| _, Error -> HandleErrorMessages j
| _, Info -> j.SelectToken "info" |> string |> this.Print
| _, null -> this.Error ("malformed message: " + x)
| _, Unknown
| _, _ -> this.Error("unknown message type: " + x)
Upvotes: 1