-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