Ocaml将字符串强制转换为元组列表

时间:2019-11-21 05:54:25

标签: casting tuples ocaml

我有文本为"[(1,2); (3,4); (5,6)]"的文件“ example.dat”。我需要从中获取元组列表。我知道,如何从整数列表中获取它。

# let f line = List.map int_of_string line;;
# open Printf
      let file = "example.dat"  
      let () =
      let ic = open_in file in
        try 
          let line = input_line ic in        
  f line;
  flush stdout;
        close_in ic
        with e ->
        close_in_noerr ic;
        raise e;;

我必须如何更改功能?

2 个答案:

答案 0 :(得分:0)

给出一个表示整数的字符串列表,您的函数f返回一个整数列表。它不返回元组列表。

您没有说是否要验证输入是否具有某种正确的形式。如果要验证其是否具有OCaml中类型为(int * int) list的列表的形式,则这是一个解析问题,将需要一些工作。

如果只想提取输入行中看起来像整数的部分,则可以从Str模块中使用正则表达式处理:

# let re = Str.regexp "[^0-9]+" in
  Str.split re "[(1,2); (37,4); (5,6)]";;
- : string list = ["1"; "2"; "37"; "4"; "5"; "6"]

然后,您可以重写函数f,以将每对整数收集到一个元组中。我看不出使用List.map的好方法。您可能必须编写自己的递归函数或使用List.fold_left

更新

我将为您编写一个将值列表更改为成对列表的函数。我希望这不是给学校做作业,在这种情况下,您应该自己弄清楚这一点。

let rec mkpairs l =
    match l with
    | [] | [_] -> []
    | a :: b :: rest -> (a, b) :: mkpairs rest

如您所见,如果列表中元素的数量为奇数,则此函数会默默地丢弃列表的最后一个元素。

此函数不是尾部递归的。因此,您可以考虑进行改进。

答案 1 :(得分:0)

    let open Genlex in
    let open Stream in
    let lexer = make_lexer ["["; "("; ","; ")"; ";"; "]";] in
    let stream = lexer (of_string array_string) in
    let fail () = failwith "Malformed string" in
    let parse_tuple acc = match next stream with
        | Int first -> ( match next stream with
            | Kwd "," -> ( match next stream with
                | Int second -> ( match next stream with
                    | Kwd ")" -> (first, second) :: acc
                    | _ -> fail () )
                | _ -> fail () )
            | _ -> fail () )
        | _ -> fail ()
    in
    let rec parse_array acc =
        match next stream with
        | Kwd "(" -> parse_array (parse_tuple acc)
        | Kwd ";" -> parse_array acc
        | Kwd "]" -> acc
        | _ -> fail ()
    in
    try
        match next stream with
            | Kwd "[" -> List.rev (parse_array [])
            | _ -> fail ()
    with Stream.Failure -> fail ();;
相关问题