模式匹配表达式:
[<EntryPoint>] let main argv = let eval x = match x with |5 -> "优" |4 -> "良" |3 -> "中" |_ -> "差" let y = eval 4 let s = Array.map eval [|3; 2; 1; 5|] 0 // 返回整数退出代码
在这里表达式中Array.map 函数,数组的每一个元素应用到eval进行模式匹配。
在模式匹配中使用条件表达式,下面定义一个分段函数:
[<EntryPoint>] let main argv = let f x = match x with | _ when (x < -1.0) -> 1.0+x | _ when (x <= 1.0) -> 0.0 | _ -> 1.0-x printfn "f(-2)= %f f(0.5)=%f f(3)=%f" (f -2.5) (f 0.5) (f 3.0) 0 // 返回整数退出代码
多参数函数:
[<EntryPoint>] let main argv = let g x y = match x,y with | (1,_) -> y | (_,1) -> 2*x | _ -> 2*x+y printfn "%i" (g 2 1) 0 // 返回整数退出代码
多个模式还可以用竖线组合在一起:
let main argv = let check pwd = match pwd with | "aaa" | "AAA" -> "密码正确" | _ -> "密码错误" let grade r = match r with | (s, _, x) when x >= 70 -> printfn "%s 通过" s | (s, '女', _) & (_, _, x) when x >= 60 -> printfn "%s 通过" s | (s, _, _) -> printfn "%s 未通过" s ("李明",'男', 68) |> grade "aaa" |> check |> printfn "%s" "AAA" |> check |> printfn "%s" 0 // 返回整数退出代码
用|表示或,用&表示与,使用管道符应用函数,我觉得这样写更加优美
使用模式匹配要注意两个重要的问题:
1.模式匹配组合要完整
2.防止永远不可能匹配的模式
记录联合,可选类型匹配
记录匹配:
type FullName = { First: string; Last: string; } [<EntryPoint>] let main argv = let IsFamily x s = match x with | { First = _; Last = fi } when fi = s -> true | _ -> false let fn = "强" let b1 = IsFamily { First = "小强"; Last = "强" } fn let b2 = IsFamily { First = "欧阳"; Last = "阳" } fn b1.ToString() |> printfn "%s" b2.ToString() |> printfn "%s" 0 // 返回整数退出代码
联合类型匹配:
type Vehicle = | Car | Truck | Bus [<EntryPoint>] let main argv = let speed x = match x with | Car -> 100 | Truck -> 60 | Bus -> 80 let mutable v1 = Car v1 |> speed |> printfn "%i" v1 <- Bus v1 |> speed |> printfn "%i" 0 // 返回整数退出代码
下面是使用模式匹配与联合类型将各种单位的长度数值转换成毫米值:
type Length = | Meter of float | Millimeter of float | Foot of float | Inch of float [<EntryPoint>] let main argv = let ToMM x = match x with | Meter x -> x * 1000.0 | Millimeter x -> x | Foot x -> x * 304.8 | Inch x -> x * 25.4 let l1,l2,l3 = Meter 3.2, Foot 0.5, Inch 8.7 printfn "l1:%.2fmm, l2:%.2fmm, l3:%.2fmm" (ToMM l1) (ToMM l2) (ToMM l3) 0 // 返回整数退出代码
可选类型匹配,可选类型本身也是一种联合类型,因此对它也可以采用模式匹配的方式:
[<EntryPoint>] let main argv = let valid x = match x with | Some(1) | Some(2) -> "不及格" | Some(x) -> "及格" | None -> "缺考" let x1, x2 = Some(5), None let y1, y2 = valid x1, valid x2 y1 |> printfn "%s" y2 |> printfn "%s" 0 // 返回整数退出代码