OCaml 中的模式匹配和嵌套模式匹配

Posted

技术标签:

【中文标题】OCaml 中的模式匹配和嵌套模式匹配【英文标题】:pattern matching and nesting pattern matching in OCaml 【发布时间】:2022-01-11 05:29:53 【问题描述】:

我有这个 OCaml 代码:


type primary_color = Red | Green | Blue

let r = Red

type point = float * float

type shape = 
    | Circle of center : point; radius : float
    | Rectangle of lower_left : point; upper_right : point
    
let c1 = Circle center = (0., 0.); radius = 1.

let r1 = Rectangle lower_left = (-1., -1.); upper_right = (1., 1.)


let avg a b = 
    (a +. b) /. 2.

以及以下计算不同形状中心的center 函数:

(* Function one using let (...) = ... *)

let center s = 
    match s with 
    | Circle center; radius -> center
    | Rectangle lower_left; upper_right -> 
        let (x_ll, y_ll) = lower_left in
        let (x_ur, y_ur) = upper_right in 
        (avg x_ll x_ur, avg y_ll y_ur)


(* Function two using nested pattern matching Rec a = ..., b = ... *)

let center s = 
    match s with 
    | Circle center; radius -> center
    | Rectangle lower_left = (x_l, y_l); upper_right = (x_r, y_r) -> 
        (avg x_l x_r, avg y_l y_r)
    | Point p -> p


我不完全理解模式语法在这里的工作方式。 在计算中心的第一个和第二个函数中,x_lly_ll 的值如何刚刚移交给函数 avg?因为 a) (x_ll, y_ll) 对没有分配给变量,b) Pairs 中的值只是在不使用 let x_ll (a, b) = a 的情况下被移交

【问题讨论】:

【参考方案1】:

center 的两个函数都在完成同样的事情。第一个只是有点迂回。 虽然第一个不匹配 Point 您之前的代码没有定义。

如果您仍然需要两个元组的名称,可以使用as

let center s = 
    match s with 
    | Circle center; radius -> center
    | Rectangle lower_left  = (x_l, y_l) as ll; 
                 upper_right = (x_r, y_r) as ur -> 
        (avg x_l x_r, avg y_l y_r)

结构模式匹配非常强大,并且不限于一定数量的级别。考虑一个非常简单的例子。

type a = b: int
type c = d: a
type e = f: c

let g = f=d=b=42

我们可以直接匹配到int

match g with
| f=d=b=n -> n

甚至可以省略=n

match g with
| f=d=b -> b

我们也可以在 let 绑定中执行此操作。

let f=d=b=n = g in
n

【讨论】:

以上是关于OCaml 中的模式匹配和嵌套模式匹配的主要内容,如果未能解决你的问题,请参考以下文章

为啥 OCaml 模式匹配比 Erlang 弱?

Ocaml模式匹配:为什么不使用此匹配?

ocaml 中的匹配是不是调用构造函数?

OCaml:在另一个内部匹配表达式?

Scala中的嵌套与展平模式匹配

截断OCaml中的列表