-3
我需要用ocaml处理来自stdin的用户输入。用户将输入命令,直到他键入退出,然后程序结束。这个怎么做?我知道如何编程必要,但我想学习功能。用户应该根据他的命令操纵堆栈中的数据。另外我想做一个解析器来处理用户命令。Ocaml stdin接口
非常感谢您的帮助!
我需要用ocaml处理来自stdin的用户输入。用户将输入命令,直到他键入退出,然后程序结束。这个怎么做?我知道如何编程必要,但我想学习功能。用户应该根据他的命令操纵堆栈中的数据。另外我想做一个解析器来处理用户命令。Ocaml stdin接口
非常感谢您的帮助!
下面是使用OCaml堆栈库可以编写的东西的草图。它远非完美,可以在很多方面得到改善,但总体结构在这里。
就您的问题而言,最重要的部分是loop
函数。它从标准输入中读取一行,并使用模式匹配来结束程序,或者评估给定和命令,并递归调用自身以等待另一个命令。
eval
函数对给定参数使用模式匹配来做正确的事情。您可以找到Stack
模块here的文档。
let stack = Stack.create()
let eval args =
match args with
| ["push"; v] -> Stack.push v stack
| ["pop"] -> begin try print_endline (Stack.pop stack) with
| Stack.Empty -> print_endline "Stack is empty"
end
| ["show"] -> Stack.iter print_endline stack
| _ -> print_endline "Unrecognized command"
let rec loop() =
match read_line() with
| "quit" -> print_endline "Bye"
| _ as command -> eval (String.split_on_char ' ' command); loop()
let() =
loop()
注意:我平时不太喜欢给人一种完整的解决方案的一个问题,这并不表明大量的研究想法,但嘿,你当你开始的地方新功能编程。
注2:此代码仅适用于string
堆栈。如果你打算存储一个不同的类型,比如说int
,或者你想要它是多态的,那么你需要稍微调整一下这些代码。
编辑:根据评论中的评论,下面是上述代码的改进版本,它不使用全局变量堆栈。
let eval s args =
match args with
| ["push"; v] -> Stack.push v s
| ["pop"] -> begin try print_endline (Stack.pop s) with
| Stack.Empty -> print_endline "Stack is empty"
end
| ["show"] -> Stack.iter print_endline s
| _ -> print_endline "Unrecognized command"
let rec loop s =
match read_line() with
| "quit" -> print_endline "Bye"
| _ as command -> eval s (String.split_on_char ' ' command); loop s
let() =
loop (Stack.create())
好吧!这是开始。非常感谢您的回答。嘿,我真的在做研究,我正在读这本书的真实世界ocaml,但我仍然没有找到像这样的简单例子。此外,我找到了一种做法,但采用更为“迫切”的方式,使用引用,但那不是我的观点,因为我想尽可能地发挥功能。再次谢谢你! – dantopa
好,真实世界OCaml可能是那里最好的资源之一。学习如何“思考”功能是相当大的挑战,tbh。如果您发现它有用,请考虑upvoting并接受答案。 – RichouHunter
使用可变/全局变量堆栈实际上并不符合功能范例的精神。更传统的方法是添加一个参数,作为eval函数的堆栈。 – ghilesZ