【问题标题】:How to convert a string to integer list in ocaml?如何在ocaml中将字符串转换为整数列表?
【发布时间】:2015-03-20 20:55:03
【问题描述】:

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

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

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

此表达式具有字符串类型,但表达式应为类型 整数列表

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

【问题讨论】:

    标签: functional-programming ocaml caml ml


    【解决方案1】:

    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 读取-评估-打印循环)。顶层将处理根据您输入的内容制作列表的工作。)

    【讨论】:

      【解决方案2】:

      由于 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 几行代码就能解决你的问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-07-22
        • 2013-09-08
        • 2020-04-24
        • 1970-01-01
        • 2015-01-14
        • 2021-06-18
        • 2022-12-18
        • 2021-09-10
        相关资源
        最近更新 更多