我正在学习 Haskell,由于这个答案的帮助,我得到了以下代码,这只是一个echo
程序。它工作得很好,但我想对其进行一些改进并且遇到了麻烦。
userInput :: MonadIO m => ReaderT (IO String) m String
userInput = ask >>= liftIO -- this liftIO eliminates your need for join
echo :: MonadIO m => ReaderT (IO String) m ()
echo = userInput >>= liftIO . putStrLn -- this liftIO is just so you can use putStrLn in ReaderT
main :: IO ()
main = runReaderT echo getLine
我想做的是更改ReaderT (IO String)
并ReaderT (i String)
使其更通用,以便我可以将其换出以进行单元测试。问题是,因为我们liftIO
在userInput
其中使用了与 . 有什么方法可以用其他东西代替来使下面的代码工作吗?i
IO
liftIO
class Monad i => MonadHttp i where
hole :: MonadIO m => i a -> ReaderT (i a) m a
instance MonadHttp IO where
hole = liftIO
newtype MockServer m a = MockServer
{ server :: ReaderT (String) m a }
deriving (Applicative, Functor, Monad, MonadTrans)
instance MonadIO m => MonadHttp (MockServer m) where
-- MockServer m a -> ReaderT (MockServer m a) m1 a
hole s = s -- What goes here?
userInput :: (MonadHttp i, MonadIO m) => ReaderT (i String) m String
userInput = ask >>= hole
echo :: (MonadHttp i, MonadIO m) => ReaderT (i String) m ()
echo = userInput >>= \input ->
((I.liftIO . putStrLn) input)
main = runReaderT echo (return "hello" :: MockServer IO String)