combining StateT with InputT

穿精又带淫゛_ 提交于 2019-11-29 11:56:07

The first error is because you have declared

main :: IO ()

but also

execStateT (...) :: IO [String]

execStateT returns the computation's final state, and your state is of type [String]. Usually this is fixed by just not declaring a type for main and letting it be inferred to be IO a for some a. The second one I'm not sure about, but maybe it's the same thing.

I'm going to take a guess at what you are trying to do.

This program recognizes the following commands:

hist        -- show current history
add xxx     -- add xxx to the history list
clear       -- clear the history list
count       -- show the count of history items
quit        -- quit the command loop

Program source:

import System.Console.Haskeline
import Control.Monad.Trans.Class
import Control.Monad.Trans.State.Strict
import Control.Monad

main :: IO ()
main = evalStateT (runInputT defaultSettings loop) []

loop :: InputT (StateT [String] IO) ()
loop = do
  minput <- getInputLine "% "
  case minput of
      Nothing -> return ()
      Just "quit" -> return ()
      Just input -> process input >> loop

process input = do
  let args = words input
  case args of
    []  -> return ()
    ("hist": _)     -> showHistory
    ("add" : x : _) -> lift $ modify (++ [x]) 
    ("clear": _)    -> lift $ modify (const [])
    ("count": _)    -> do hs <- lift get
                          outputStrLn $ "number of history items: " ++ show (length hs)
    _               -> outputStrLn "???"

showHistory = do
  hist <- lift get
  forM_ (zip [(1::Int)..] hist) $ \(i,h) -> do
    outputStrLn $ show i ++ " " ++ h

The code you have here compiles, and it defines process as:

process :: Counter -> String -> IO ()

To create a version of process with this signature:

Counter -> String -> InputT (StateT [String] IO) ()

just use liftIO:

process' :: Counter -> String -> InputT (StateT [String] IO) ()
process' counter str = liftIO $ process counter str
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!