Hi Francesco,
Thank you for your response, it definitely helped. Below is an updated version of working code. Where I was getting tripped up earlier was in the commented portion below. Also, if you scroll down further, I have a few further questions. Thank you for your time.
module Main where
import Evaluator
import System.Console.Haskeline
main :: IO ()
main = runInputT defaultSettings loop
where
loop :: InputT IO ()
loop = do
line <- getInputLine ">> "
case line of
Nothing -> return ()
Just input -> do
let (result, next) = evaluate input
if (next == Return)
then return ()
else (emit result >> loop) -- I had wanted the result to be emitted only on Continue, not Return. This works, but is it a good way?
emit :: Maybe String -> InputT IO ()
emit Nothing = return ()
emit (Just value) = outputStrLn $ "Executing: " ++ value
module Evaluator where
data Next = Continue | Return
deriving (Eq, Ord)
evaluate :: String -> (Maybe String, Next) -- Now updated to make the first part of the tuple a Maybe String instead of String
evaluate "quit" = (Nothing, Return)
evaluate value = (Just value, Continue)
** QUESTIONS **
1. If I wanted to write the logic encapsulated in `emit' directly within main, how would I do that? In my example, I was forced to extract it out as a separate method specifically to leverage pattern matching.
2. You mentioned outputStrLn has a type `String -> InputT IO ()'. How do you logically come to this conclusion? Is it because outputStrLn was taking a single String argument and had to return the same type returned by loop declared previously?
3. Are there better/simpler/more idiomatic ways of structuring my program?