F#与复杂类型匹配

F#与复杂类型匹配,f#,pattern-matching,F#,Pattern Matching,我是F#的新手,我正在尝试用复杂类型进行简单的模式匹配,但我找不到方法。请参阅下面的伪代码,以解释我要进行的模式匹配 type Vector= {X:int; Y:int} let calculateDirection vector = match vector with | vector.X=0 && vector.Y>0 -> "N" // pseudo code | vector.X>0 && vector.Y>0 -&g

我是F#的新手,我正在尝试用复杂类型进行简单的模式匹配,但我找不到方法。请参阅下面的伪代码,以解释我要进行的模式匹配

type Vector= {X:int; Y:int}

let calculateDirection vector = 
match vector with
| vector.X=0 && vector.Y>0 -> "N"    // pseudo code 
| vector.X>0 && vector.Y>0 -> "NE"   // pseudo code 
| vector.X>0 && vector.Y=0 -> "E"    // pseudo code 
| vector.X>0 && vector.Y<0 -> "SE"   // pseudo code 
| vector.X=0 && vector.Y<0 -> "S"    // pseudo code 
| vector.X<0 && vector.Y<0 -> "SW"   // pseudo code 
| vector.X<0 && vector.Y=0 -> "W"    // pseudo code 
| vector.X<0 && vector.Y>0 -> "NW"   // pseudo code 
| _ -> "Error"
type Vector={X:int;Y:int}
让calculateDirection向量=
匹配向量
|vector.X=0&&vector.Y>0->“N”//pseudo code
|vector.X>0&&vector.Y>0->“NE”//伪代码
|vector.X>0&&vector.Y=0->“E”//伪代码
|vector.X>0&&vector.Y“SE”//pseudo代码
|vector.X=0&&vector.Y“S”//伪代码
|vector.X“NW”//pseudo代码
|->“错误”
我读了一些教程(),但都是简单的场景,对我帮助不大。或者我就是不太明白


提前感谢。

要匹配记录,可以使用记录匹配语法,这与记录构造语法类似:

match vector with
| { X = x; Y = y } -> sprintf "Vector (%d, %d)" x y
您也可以将其与防护装置结合使用:

match vector with
| { X = 0; Y = y } when y > 0 -> "N"
| { X = x; Y = y } when x > 0 && y > 0 -> "NE"
| { X = x; Y = 0 } when x > 0 -> "E"
...
但这看起来有点难看。为了帮助解决这个问题,您还可以构建自己的匹配器(也称为“活动模式”)——它和常规函数类似,但可以用于匹配。它们有一种有趣的语法:

let (|Positive|_|) x = if x > 0 then Some() else None
let (|Negative|_|) x = if x < 0 then Some() else None

match vector with
| { X = 0; Y = Positive } -> "N"
| { X = Positive; Y = Positive } -> "NE"
| { X = Positive; Y = 0 } -> "E"
| { X = Positive; Y = Negative } -> "SE"
...
let(|正| | |)x=如果x>0,则其他一些()无
设(|负| | | |)x=如果x<0,则某些()其他无
匹配向量
|{X=0;Y=正}->“N”
|{X=正;Y=正}->“NE”
|{X=正;Y=0}->“E”
|{X=正;Y=负}->“SE”
...

使用活动模式,您可以获得如下非常可读的代码:

type Vector= {X:int; Y:int}

let (|West|_|) v = if v.X < 0 then Some () else None
let (|East|_|) v = if v.X > 0 then Some () else None
let (|North|_|) v = if v.Y > 0 then Some () else None
let (|South|_|) v = if v.Y < 0 then Some () else None

let calculateDirection = function
    | North & East -> Some "NE"
    | North & West -> Some "NW"
    | North -> Some "N"
    | South & East -> Some "SE"
    | South & West -> Some "SW"
    | South -> Some "S"
    | East -> Some "E"
    | West -> Some "W"
    | _ -> None
type Vector={X:int;Y:int}
设(| West | | | |)v=如果v.X<0,则一些()其他无
设(|东| | | |)v=如果v.X>0,则一些()其他无
设(|北| | | |)v=如果v.Y>0,则一些()其他无
设(|南| | | |)v=如果v.Y<0,则一些()其他无
让calculateDirection=函数
|北和东->一些“东北”
|北和西->一些“西北”
|北->一些“N”
|东南->一些“东南”
|西南->一些“西南”
|南->一些“S”
|东->一些“E”
|西->一些“W”
|无

谢谢,它工作得很好,我使用了活动模式解决方案,因为它的可读性确实更好。这确实是另一个很好的解决方案,谢谢你的回答,因为我昨天已经接受了第一个解决方案,但这真的很好,可能因为活动模式的选择更好,所以可读性更强。