haskell / haskeline

A Haskell library for line input in command-line programs.
https://hackage.haskell.org/package/haskeline
BSD 3-Clause "New" or "Revised" License
223 stars 75 forks source link

Cannot use haskeline input for system commands #132

Closed JesterOrNot closed 4 years ago

JesterOrNot commented 4 years ago

here is the code https://github.com/JesterOrNot/HaskShell/blob/haskeline/src/main.hs I get this

[1 of 1] Compiling Main             ( src/main.hs, src/main.o )

src/main.hs:18:33: error:
    • Couldn't match type ‘IO’ with ‘InputT IO’
      Expected type: InputT IO ()
        Actual type: IO ()
    • In a stmt of a 'do' block: callCommand input
      In the expression:
        do callCommand input
           loop
      In a case alternative:
          Just input
            -> do callCommand input
                  loop
   |
18 |                                 callCommand input
   |                                 ^^^^^^^^^^^^^^^^^

when trying

loop = do
           minput <- getInputLine "\x1b[1;34mHaskShell> \x1b[0m"
           case minput of
               Just "" -> loop
               Just "exit" -> return ()
               Just input -> do 
                                callCommand input
                                loop
               Nothing -> return ()
judah commented 4 years ago

This behavior is expected. The issue you're running into is a mismatch between actions:

getInputLine "..." :: InputT IO String
callCommand input :: IO ...

The fix is to take advantage of InputT being a "monad transformer" and lifting callCommand into InputT IO it using either lift or liftIO. For example:

Just input -> do
    lift (callCommand input)
    loop

Some references: http://book.realworldhaskell.org/read/monad-transformers.html https://wiki.haskell.org/Monad_Transformers

JesterOrNot commented 4 years ago

Now I'm getting

[1 of 1] Compiling Main             ( src/main.hs, src/main.o )

src/main.hs:18:20: error:
    Variable not in scope: lift :: IO () -> InputT IO a0
   |
18 |                    lift (callCommand input)
   |                    ^^^^

Sorry I'm very new to Haskell (but fortunately not programming)

judah commented 4 years ago

It's defined here: http://hackage.haskell.org/package/transformers-0.5.6.2/docs/Control-Monad-Trans-Class.html#v:lift