Functional programming 模式匹配和构造函数

Functional programming 模式匹配和构造函数,functional-programming,pattern-matching,ocaml,Functional Programming,Pattern Matching,Ocaml,为什么在编写这种模式匹配时会出现错误: 类型t=A的int | B的float 设f=函数 |(A i | B f)->正确 |_u->false 或 设f=函数 |A i | B f->正确 |_u->false 错误:变量f必须出现在此|模式的两侧 设f=函数 |(A i | B i)->正确 |_u->false 或 设f=函数 |A i | B i->正确 |_u->false 错误:此模式与float类型的int类型值匹配 但需要与值匹配的模式 在或模式(|模式)中,您将无法跟

为什么在编写这种模式匹配时会出现错误:

类型t=A的int | B的float
设f=函数
|(A i | B f)->正确
|_u->false

设f=函数
|A i | B f->正确
|_u->false
错误:变量f必须出现在此|模式的两侧

设f=函数
|(A i | B i)->正确
|_u->false

设f=函数
|A i | B i->正确
|_u->false
错误:此模式与float类型的int类型值匹配 但需要与值匹配的模式


模式(
|
模式)中,您将无法跟踪您所处的构造函数。因此,您需要绑定同一组变量才能工作,而无需引用构造函数

OCaml是强类型的;值
i
不能同时具有类型
int
和类型
float

如果类型
t
有两个以上的案例,您应该写:

let f = function
        | A _ | B _ -> true
        | _ -> false
否则:

let f = function
        | A _ | B _ -> true
这就足够了,因为模式匹配已经是穷尽的了

我同意,
模式是非常严格的,但有时当函数中有对称情况时,它是有用的:

type num = 
    | Int of int
    | Float of float

let add s1 s2 = 
    match s1, s2 with
    | Int i1, Int i2 -> Int (i1 + i2)
    | Int i, Float f | Float f, Int i -> Float (float i +. f)
    | Float f1, Float f2 -> Float (f1 +. f2)

模式(
|
模式)中,您将无法跟踪您所处的构造函数。因此,您需要绑定同一组变量才能工作,而无需引用构造函数

OCaml是强类型的;值
i
不能同时具有类型
int
和类型
float

如果类型
t
有两个以上的案例,您应该写:

let f = function
        | A _ | B _ -> true
        | _ -> false
否则:

let f = function
        | A _ | B _ -> true
这就足够了,因为模式匹配已经是穷尽的了

我同意,
模式是非常严格的,但有时当函数中有对称情况时,它是有用的:

type num = 
    | Int of int
    | Float of float

let add s1 s2 = 
    match s1, s2 with
    | Int i1, Int i2 -> Int (i1 + i2)
    | Int i, Float f | Float f, Int i -> Float (float i +. f)
    | Float f1, Float f2 -> Float (f1 +. f2)

如果您为多个模式提供了一个单独的右侧(正如您所做的),OCaml要求模式一致地绑定到模式变量

在第一种情况下

match ... with
  | A i | B f -> ...
  ...
match ... with
  | A i | B i -> ...
  ...
这些模式在绑定到的变量上不一致:第一个模式绑定到
i
,而第二个模式绑定到
f

在第二种情况下

match ... with
  | A i | B f -> ...
  ...
match ... with
  | A i | B i -> ...
  ...
模式在绑定到变量的值类型上不一致:第一个模式将
int
类型的值绑定到
i
,而第二个模式将
float
类型的值绑定到
i

这两种模式能够始终绑定到变量的唯一方法是根本不绑定到任何变量:

match ... with
  | A _ | B _ -> ...
  ...
然后,完整的示例变成

type t = A of int | B of float

let f = function
  | A _ | B _ -> true
  | _ -> false
(但请注意,模式匹配的最后一个部分是多余的,因为前两个模式已经完全匹配了类型
t
的所有值。因此,我们得到:

let f = function
  | A _ | B _ -> true

当然,这相当于编写
let f=true

如果您为多个模式提供了一个单独的右侧(正如您所做的那样),OCaml要求模式一致地绑定到模式变量

在第一种情况下

match ... with
  | A i | B f -> ...
  ...
match ... with
  | A i | B i -> ...
  ...
这些模式在绑定到的变量上不一致:第一个模式绑定到
i
,而第二个模式绑定到
f

在第二种情况下

match ... with
  | A i | B f -> ...
  ...
match ... with
  | A i | B i -> ...
  ...
模式在绑定到变量的值类型上不一致:第一个模式将
int
类型的值绑定到
i
,而第二个模式将
float
类型的值绑定到
i

这两种模式能够始终绑定到变量的唯一方法是根本不绑定到任何变量:

match ... with
  | A _ | B _ -> ...
  ...
然后,完整的示例变成

type t = A of int | B of float

let f = function
  | A _ | B _ -> true
  | _ -> false
(但请注意,模式匹配的最后一个部分是多余的,因为前两个模式已经完全匹配了类型
t
的所有值。因此,我们得到:

let f = function
  | A _ | B _ -> true
这当然相当于编写
让f=true