Я написал небольшой фрагмент кода, который обрабатывает ввод с консоли:
main :: IO ()
main = do
input <- readLine "> "
loop input
loop :: String -> IO ()
loop input = do
case input of
[] -> do
new <- readLine "> "
loop new
"quit" ->
return ()
_ -> do
handleCommand input
new <- readLine "> "
loop new
handleCommand :: String -> IO ()
handleCommand command = do
case command of
"a" -> putStrLn "it was a"
"b" -> putStrLn "it was b"
_ -> putStrLn "command not found"
readLine :: String -> IO String
readLine prompt = do
putStr prompt
line <- getLine
return line
Код работает нормально, но выглядит уродливо и избыточно.В Scala мне удалось написать его короче:
object Test extends App {
val reader = Iterator.continually(readLine("> "))
reader takeWhile ("quit" !=) filter (_.nonEmpty) foreach handleCommand
def handleCommand(command: String) = command match {
case "a" => println("it was a")
case "b" => println("it was b")
case _ => println("command not found")
}
}
Я пытался использовать функции высшего порядка с монадой ввода-вывода в Haskell, но потерпел неудачу.Может кто-нибудь привести пример, как сократить код на Haskell?
Другая проблема заключается в том, что порядок вывода отличается.В Scala это правильно:
$ scala Test
> hello
command not found
> a
it was a
> b
it was b
> quit
В то время как в Haskell это не так:
$ ./test
hello
> command not found
a
> it was a
b
> it was b
quit
> %
Как это решить?