如何将字符串转换为ocaml中的整数列表?

时间:2015-01-22 06:23:46

标签: functional-programming ocaml caml ml

我需要在ocaml中传递两个列表作为命令行参数。 我使用以下代码在程序中访问它。

let list1=Sys.argv.(1);;
let list2=Sys.argv.(2);;

我需要将list1和list2作为整数列表。 我收到了错误

  

此表达式具有类型字符串,但表达式需要类型            int list

处理时

如何将该参数转换为整数列表。 参数以这种格式传递[1; 2; 3; 4] [1; 5; 6; 7]

2 个答案:

答案 0 :(得分:2)

Sys.argv.(n)将永远是一个字符串。您需要将字符串解析为整数列表。你可以尝试这样的事情:

$ ocaml
        OCaml version 4.01.0

# #load "str.cma";;
# List.map int_of_string (Str.split (Str.regexp "[^0-9]+") "[1;5;6;7]");;
- : int list = [1; 5; 6; 7]

当然,这并没有检查输入是否正确。它只是通过蛮力拉出数字序列。为了做得更好,你需要做一些真正的词法分析和简单的解析。

(也许这很明显,但您也可以在顶层(OCaml read-eval-print循环)中测试您的函数。顶层将处理根据您输入的内容制作列表的工作。)

答案 1 :(得分:0)

由于Sys.argv是string array,你需要编写自己的转录函数。

我想最简单的方法是使用标准库提供的Genlex模块。

let lexer = Genlex.make_lexer ["["; ";"; "]"; ]
let list_of_string s =
  let open Genlex in
  let open Stream in
  let stream = lexer (of_string s) in
  let fail () = failwith "Malformed string" in
  let rec aux acc =
    match next stream with
    | Int i ->
      ( match next stream with
        | Kwd ";" -> aux (i::acc)
        | Kwd "]" -> i::acc
        | _ -> fail () )
    | Kwd "]" -> acc
    | _ -> fail ()
  in
  try
    match next stream with
    | Kwd "[" -> List.rev (aux [])
    | _ -> fail ()
  with Stream.Failure -> fail ()

let list1 = list_of_string Sys.argv.(1)
let list2 = list_of_string Sys.argv.(2)

根据您想要使用的OCaml风味,其他一些库可能看起来更有趣。如果您喜欢yacc,Menhir可以通过几行代码解决您的问题。