如何在F#中的HttpMethod上进行模式匹配?

时间:2022-02-02 13:08:59

Where request is a HttpRequestMessage from System.Net.Http, I'm trying to use pattern matching to determine which method was used to make the request.

如果请求是来自System.Net.Http的HttpRequestMessage,我正在尝试使用模式匹配来确定用于发出请求的方法。

This is a contrived example which demonstrates my problem:

这是一个人为的例子,它证明了我的问题:

let m = match request.Method with
      | HttpMethod.Get -> "GET"
      | HttpMethod.Post -> "POST"

which results in:

这导致:

Parser error: The field, constructor or member 'Get' is not defined

分析器错误:未定义字段,构造函数或成员“Get”

Why doesn't this work, and how can I use pattern matching or a more appropriate technique to achieve the same goal?

为什么这不起作用,我如何使用模式匹配或更合适的技术来实现相同的目标?

2 个解决方案

#1


As John Palmer points out in his comment, you could write it like this:

正如John Palmer在评论中指出的那样,你可以像这样写:

let m =
    match request.Method with
    | x when x = HttpMethod.Get -> "GET"
    | x when x = HttpMethod.Post -> "POST"
    | _ -> ""

However, if you're going to be doing this repeatedly, you may find this a bit cumbersome, in which case you could define some Active Patterns for it:

但是,如果你要重复这样做,你可能会发现这有点麻烦,在这种情况下你可以为它定义一些活动模式:

let (|GET|_|) x =
    if x = HttpMethod.Get
    then Some x
    else None

let (|POST|_|) x =
    if x = HttpMethod.Post
    then Some x
    else None

Which would enable you to write this:

哪个可以让你写这个:

let m =
    match request.Method with
    | GET _ -> "GET"
    | POST _ -> "POST"
    | _ -> ""

#2


Another approach with Active Patterns which ends up with a slightly nicer code than in Mark's solution would be a pattern function like this one (using full classification pattern):

使用活动模式的另一种方法最终得到的代码比Mark的解决方案稍好一些,就像这样的模式函数(使用完整的分类模式):

let (|GET|POST|PUT|DELETE|OTHER|) x =
    if x = HttpMethod.Get
    then GET
    elif x = HttpMethod.Post
    then POST
    elif x = HttpMethod.Put
    then PUT
    elif x = HttpMethod.Delete
    then DELETE
    else OTHER

This approach lets you get rid of underscores in pattern matching:

这种方法可以让你摆脱模式匹配中的下划线:

let m =
    match request.Method with
    | GET -> "GET"
    | POST -> "POST"
    | _ -> ""

#1


As John Palmer points out in his comment, you could write it like this:

正如John Palmer在评论中指出的那样,你可以像这样写:

let m =
    match request.Method with
    | x when x = HttpMethod.Get -> "GET"
    | x when x = HttpMethod.Post -> "POST"
    | _ -> ""

However, if you're going to be doing this repeatedly, you may find this a bit cumbersome, in which case you could define some Active Patterns for it:

但是,如果你要重复这样做,你可能会发现这有点麻烦,在这种情况下你可以为它定义一些活动模式:

let (|GET|_|) x =
    if x = HttpMethod.Get
    then Some x
    else None

let (|POST|_|) x =
    if x = HttpMethod.Post
    then Some x
    else None

Which would enable you to write this:

哪个可以让你写这个:

let m =
    match request.Method with
    | GET _ -> "GET"
    | POST _ -> "POST"
    | _ -> ""

#2


Another approach with Active Patterns which ends up with a slightly nicer code than in Mark's solution would be a pattern function like this one (using full classification pattern):

使用活动模式的另一种方法最终得到的代码比Mark的解决方案稍好一些,就像这样的模式函数(使用完整的分类模式):

let (|GET|POST|PUT|DELETE|OTHER|) x =
    if x = HttpMethod.Get
    then GET
    elif x = HttpMethod.Post
    then POST
    elif x = HttpMethod.Put
    then PUT
    elif x = HttpMethod.Delete
    then DELETE
    else OTHER

This approach lets you get rid of underscores in pattern matching:

这种方法可以让你摆脱模式匹配中的下划线:

let m =
    match request.Method with
    | GET -> "GET"
    | POST -> "POST"
    | _ -> ""