OCaml:在与结构匹配的内部引发错误

时间:2015-06-04 02:33:34

标签: exception functional-programming ocaml match

在OCaml中,我有一个包含城镇名称的字符串列表(例如“1-New York; 2-London; 3-Paris”)。我需要让用户输入一个数字(如果他们想要伦敦他们必须输入2)。 我想提出一个异常消息,说该镇无效,如果该人在示例中键入例如“4”。 我试过这个,但它不起作用:

let chosenTown = match int_of_string (input_line stdin) with | x > (length listOfTowns) -> raise (Err "Not a valid town")

编码的好方法是“如果所选数字大于列表长度,则会引发错误”??

2 个答案:

答案 0 :(得分:1)

模式不能包含任意表达式。它可以是常量,构造函数名称,花括号内的记录字段,列表,数组等。

但是可以保护模式,例如

match int_of_string (input_line stding) with
| x when x >= length listOfTowns -> 
 invalid_arg "the number is too large"
| x -> List.nth listOfTowns x 

答案 1 :(得分:0)

为了完成答案,模式匹配依赖于统一,并且不期望断言(它不等于switch中的C左右。)

这个想法是你提供不同的“形状”(模式),你的术语(你匹配的东西)可以有。 例如:

match l with
| e :: e' :: r -> (*...*)
| e :: r       -> (*...*)
| []           -> (*...*)

它还具有绑定效果,如果您传递,例如[1](确实是一个非常小的列表),它将与e :: e' :: r不匹配,但会匹配e :: r和然后是e = 1r = []

正如ivg所说,由于关键字when,您可以添加条件,这次是布尔值。

但是,在操作这样的列表时,我会选择递归函数:

let rec find_town n l =
  match l with
  | t :: _ when n = 1 -> t
  | _ :: r            -> find_town (n-1) r
  | []                -> raise (Err "Not a valid town")

这基本上是再次写List.nth,但更改了它引发的异常。