adding state monad to the haskell kv database
<p>Playing with an old code review here <a href="https://codereview.stackexchange.com/questions/24741/simple-in-memory-db">simple-db</a>. and get stuck when I added State Monad into it to further reduce the code. </p>

<p>I somehow feel I am not doing it correctly. <code>repl cmd = getCmd &gt;&gt;= execCmd cmd &gt;&gt;= displayResult &gt;&gt;= continue</code>  change the interface of <code>execCmd</code> means change all the functions along the line. </p>

<p><strong>if I follow this approach, how to get it work?</strong> </p>

<p><strong>what's the correct way of doing the suggested refactoring using <code>state</code> Monad ?</strong></p>

<pre><code>--import qualified
import Data.Map as M
import Control.Monad.State

type History = [String]

data Result = Result (Maybe String) Bool

data Command = Invalid | End | Get String | Set String String
data DB = DB (M.Map String String)


execCmd :: Command -&gt; State DB Result
execCmd (Set key val) = do
  (db@(DB map), r) &lt;- get
  let newMap = M.insert key val map
  put ((DB newMap), r)
  return $ Result Nothing False 
execCmd (Get key) = do
  (db@(DB map), r) &lt;- get
  return $ Result (M.lookup key map) False 
execCmd End = do
  return $ Result Nothing True 
execCmd Invalid = do
  return $ Result Nothing False 

getCmd = getLine &gt;&gt;= return . parseCmd

parseCmd :: String -&gt; Command
parseCmd s =
  case words s of
    ("set":key:value:_) -&gt; Set key value
    ("get":key:_)       -&gt; Get key
    ("end":_)           -&gt; End
    _                   -&gt; Invalid

displayResult :: Result -&gt; IO Result
displayResult r@(Result (Just s) _ ) = putStrLn s &gt;&gt; return r
displayResult r                      = return r

continue :: Result -&gt; IO ()
continue (Result _ end) = if end then return () else repl 

repl cmd = getCmd &gt;&gt;= execCmd cmd &gt;&gt;= displayResult &gt;&gt;= continue

startState = ((DB M.empty), (Result Nothing False))

--main = repl Invalid 
</code></pre>