【发布时间】:2016-10-28 09:07:11
【问题描述】:
我正在尝试将http://lexi-lambda.github.io/blog/2016/06/12/four-months-with-haskell/(标题为“Typeclasses 可以模拟效果”的部分)提供的方法与某种本土阅读器 monad 结合起来。
我要解决的总体问题是避免将配置变量传递给我的应用程序中几乎所有功能。我不能使用ReaderT 的原因是因为我的很多函数都在SqlPersistT 中,它本身在内部使用ReaderT。另一个原因是更好地学习所有这些心理体操。
我的两个问题在下面的代码中以 cmets 的形式给出。在这里也复制它们:
- 定义
NwMonad的最合适方式是什么? - 因此,如何将
NwMonad定义为HasNwConfig的实例?askNwConfig的函数体怎么写? - 我最后怎么打电话给
runNwMonad?它的论点是什么?
代码如下:
data NwConfig = NwConfig {
_googleClientId :: T.Text,
_googleClientSecret :: T.Text,
_tgramBotToken :: String,
_aria2Command :: String,
_aria2DownloadDir :: String
}
$(makeLenses ''NwConfig)
instance Default NwConfig where
def = NwConfig{}
class MonadIO m => HasNwConfig m where
askNwConfig :: m NwConfig
startAria2 :: (HasNwConfig m) => m Sytem.Process.ProcessHandle
cfg <- askNwConfig
(_, _, _, processHandle) <- createProcess $ proc (cfg ^. aria2Command) []
return processHandle
-- QUESTION: Is this correct?
data NwMonad a = NwMonad{runNwMonad :: (NwConfig -> IO a)}
deriving (Functor, Applicative, Monad, MonadIO)
-- Or is this the way to do it?
data NwMonad a = NwMonad{runNwMonad :: IO a, nwConfig :: NwConfig}
deriving (Functor, Applicative, Monad, MonadIO)
instance HasNwConfig NwMonad where
askNwConfig = return . nwConfig -- QUESTION: How to write this?
main :: IO ()
main = do
[cId, cSecret, botToken] <- sequence [getEnv "GOOGLE_CLIENT_ID", getEnv "GOOGLE_CLIENT_SECRET", getEnv "TELEGRAM_TOKEN"]
let cfg = (def :: NwConfig)
& googleClientId .~ (T.pack cId)
& googleClientSecret .~ (T.pack cSecret)
& tgramBotToken .~ botToken
& aria2Command .~ "/Users/saurabhnanda/projects/nightwatch/aria2-1.19.3/bin/aria2c"
-- QUESTION: How do I use this now?
runNwMonad $ (?????) $ startAria2
【问题讨论】:
-
如果你包含你的导入会有所帮助。
标签: haskell monads monad-transformers reader-monad