I have written a small piece of code which handles the input of a console:
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
The code works fine, but it looks ugly and is redundant. In Scala I succeeded to write it shorter:
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")
}
}
I tried to use higher-order functions with the IO Monad in Haskell but I failed. Can someone give me an example how to shorten the Haskell code?
Another problem is that the order of output is different. In Scala it is correct:
$ scala Test
> hello
command not found
> a
it was a
> b
it was b
> quit
Whereas in Haskell it is not:
$ ./test
hello
> command not found
a
> it was a
b
> it was b
quit
> %
How to solve this?
import System.IO
main = putStr "> " >> hFlush stdout >> getLine >>= \input ->
case input of
"quit" -> return ()
"a" -> putStrLn "it was a" >> main
"b" -> putStrLn "it was b" >> main
_ -> putStrLn "command not found" >> main
Shorter and clearer than Scala imo.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With