这是我参与11月更文挑战的第14天,活动详情查看:2021最后一次更文挑战」
我们通常会用到如下几个模式匹配:
p1 | ... | pn: 选择模式(or),从左到右,如果其中pi匹配成功就返回正确。所有的模式必须绑定同样的变量(p : t):显式匹配类型c: 这里c为常量,可以是整数、布尔类型的'ch1'..'ch2':ch说明这是一个字符。例如'A'..'Z'匹配所有的大些字母p when e:当e为true是匹配p
more pattern forms : link
用Let进行模式匹配
syntax
let表达式的用法实际上是一个特殊的语法结构
let p = e1 in e2
左边实际上一个模式,不仅仅是变量名。当然,变量的标识符也是我们合法模式的一个匹配。之前,一个let的定义被认为let表达式的body是没有给出的。所以,可以推出
let p = e
用函数进行模式匹配
let f p1 ... pn = e1 in e2 (* function as part of let expression *)
let f p1 ... pn = e (* function definition at toplevel *)
fun p1 ... pn -> e (* anonymous function *)
Examples
utop # (* Pokmon types *)
type ptype = TNormal | TFire | TWater;;
type ptype = TNormal | TFire | TWater
utop # (* A record to represent Pokmon *)
type mon = { name : string; hp : int; ptype: ptype };;
type mon = { name : string; hp : int; ptype : ptype; }
utop # (* OK *)
let get_hp m = match m with { name =n; hp = h; ptype = t } -> h;;
val get_hp : mon -> int = <fun>
utop # (* better *)
let get_hp m = match m with { name = _; hp = h; ptype = _ } -> h;;
val get_hp : mon -> int = <fun>
utop # (* better *)
let get_hp m = match m with {name; hp; ptype } -> hp;;
val get_hp : mon -> int = <fun>
utop # (* best *)
let get_hp m = m.hp;;
val get_hp : mon -> int = <fun>
这里我们可以通过如下的方式获得一个pair的第一个和第二个元素
utop # let fst (x, _) = x;;
val fst : 'a * 'b -> 'a = <fun>
utop # let snd (_, y) = y;;
val snd : 'a * 'b -> 'b = <fun>
这里的fst和snd已经存在标准库中。同理可以扩展到三元组上面。
Type Synonyms
类型的同名对已经存在的类型的新的名字。比如:
utop # type point = float * float;;
type point = float * float
utop # type vector = float list;;
type vector = float list
utop # type matrix = float list list;;
type matrix = float list list
在其他地方,你可以用point来代替float * float。
utop # let get_x = fun (x, _) -> x;;
val get_x : 'a * 'b -> 'a = <fun>
utop # let p1 :point = (1., 2.);;
val p1 : point = (1., 2.)
utop # let p2 : float * float = (1., 3.);;
val p2 : float * float = (1., 3.)
utop # let a = get_x p1;;
val a : float = 1.
utop # let b = get_x p2;;
val b : float = 1.