首页 文章

在OCaml中匹配sum类型时绑定名称

提问于
浏览
2

在OCaml中,是否可以在模式匹配时将名称绑定到数据构造函数的内容?作为一个说明性示例,假设我有以下OCaml程序:

type t = A of int * int | B of int * int

let sum_pair (a, b) = a + b

let f x = match x with
  | A (a1, a2) -> sum_pair (a1, a2)
  | B (_, b) -> b

let _ = Printf.printf "%d\n" (f (A (1, 2)))

这编译,但是我需要在匹配后重建元组 (a1, a2) 并将其传递给 sum_pair ,这相当烦人!相反,我希望能够写作

let f x = match x with
  | A (_ as pair) -> sum_pair pair
  | B (_, b) -> b

但这失败了“错误:构造函数A需要2个参数,但这里应用于1个参数 . ”写作

let f x = match x with
  | A _ as pair -> sum_pair pair
  | B (_, b) -> b

并不是更好,因为它将 pair 绑定到整个值,而不是内部的对 . (这也无法编译,正如您所期望的那样:"This expression has type t but an expression was expected of type int * int.")

1 回答

  • 5

    如果您以这种方式定义类型,则可以使其工作:

    type t = A of (int * int) | B of (int * int)
    

    这意味着构造函数A实际上接受了一个参数,即_2393303没有办法解决这个问题 .

    # type t = A of (int * int) | B of (int * int);;
    type t = A of (int * int) | B of (int * int)
    
    # let sum_pair (a, b) = a + b 
    
      let f x = match x with
      | A p -> sum_pair p
      | B (_, b) -> b
      ;;
    val sum_pair : int * int -> int = <fun>
    val f : t -> int = <fun>
    
    # f (A (5, 7));;
    - : int = 12
    

    这是OCaml语法的棘手问题 . 这是最近的另一个讨论:'as' Keyword in Pattern Matching Behaving Strangely .

相关问题