我試圖結合在http://lexi-lambda.github.io/blog/2016/06/12/four-months-with-haskell/(標題爲「Typeclasses可以模擬效果」一節)給出的方法與某種本土讀者monad。如何構建自定義閱讀器monad以及自定義類型類別?
我試圖解決的總體問題是避免傳遞一個配置變量幾乎在我的應用程序中運行。而我不能使用ReaderT
的原因是因爲我的很多功能都在SqlPersistT
中,它本身在內部使用ReaderT
。另一個原因是要更好地學習所有這些心理體操。
我的兩個問題在下面的代碼中給出了註釋。在這裏重現它們:
- 什麼是定義
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
這將有助於如果你包括你的進口。 – ErikR