evalLoop :: Stack -> Env -> InputT IO ()
evalLoop p m = do
    let text = case p of
                 [] -> ""
                 s -> showStack s ++ " "
    minput <- getInputLineWithInitial ": " (text, "")
    case minput of
      Nothing -> return ()
      Just "" -> return ()
      Just input -> case parseStack input of
        Left e -> outputStrLn (show e) >> evalLoop p m
        Right s -> do
          let x' = runIdentity $ evalStack (subst (A "IO") Io s, m, ([], []))
          case take 5 x' of
            [] -> evalLoop s m
            ((s',m',c'):r) -> do
              mapM_ printAlt $ reverse r
              printConstraints c'
              evalLoop s' m'
  where printConstraints (c,_) =
          mapM_ (\(x, y) -> outputStrLn $ showStack x ++ " <-- " ++ showStack y) $ reverse c
        printAlt (s,_,c) = do
          printConstraints c
          outputStrLn . ("| "++) . showStack $ s
evalLoop :: Stack -> Env -> InputT IO ()
evalLoop p m = do
    let text = case p of
                 [] -> ""
                 s -> showStack s ++ " "
    minput <- getInputLineWithInitial ": " (text, "")
    case minput of
      Nothing -> return ()
      Just "" -> return ()
      Just input -> case parseStack input of
        Left e -> outputStrLn (show e) >> evalLoop p m
        Right s -> do
          let x' = runIdentity $ evalStack (subst (A "IO") Io s, m, ([], []))
          case take 5 x' of
            [] -> evalLoop s m
            ((s',m',c'):r) -> do
              mapM_ printAlt $ reverse r
              printConstraints c'
              evalLoop s' m'
  where printConstraints (c,_) =
          mapM_ (\(x, y) -> outputStrLn $ showStack x ++ " <-- " ++ showStack y) $ reverse c
        printAlt (s,_,c) = do
          printConstraints c
          outputStrLn . ("| "++) . showStack $ s
evalLoop p m = do
    let text = case p of
                 [] -> ""
                 s -> showStack s ++ " "
    minput <- getInputLineWithInitial ": " (text, "")
    case minput of
      Nothing -> return ()
      Just "" -> return ()
      Just input -> case parseStack input of
        Left e -> outputStrLn (show e) >> evalLoop p m
        Right s -> do
          let x' = runIdentity $ evalStack (subst (A "IO") Io s, m, ([], []))
          case take 5 x' of
            [] -> evalLoop s m
            ((s',m',c'):r) -> do
              mapM_ printAlt $ reverse r
              printConstraints c'
              evalLoop s' m'
  where printConstraints (c,_) =
          mapM_ (\(x, y) -> outputStrLn $ showStack x ++ " <-- " ++ showStack y) $ reverse c
        printAlt (s,_,c) = do
          printConstraints c
          outputStrLn . ("| "++) . showStack $ s