【发布时间】:2020-06-16 00:22:58
【问题描述】:
我正在遵循 on this video by Ben Kolera 提出的构建模块化 Haskell 应用程序的建议。
建议使用多个 monad 转换器,以使应用程序模块化和组织化。建议使用自定义 liftModule 函数将这些 monad 组合在一起。
例如,我们有一个主要的App 模块和一个Logic 模块。
newtype App a = App
{ unApp :: ExceptT AppError (ReaderT AppEnv IO) a }
newtype Logic a = Logic
{ unLogic :: ExceptT LogicError (Reader LogicEnv) a }
liftLogic 定义如下。
runLogic :: LogicEnv -> Logic a -> Either LogicError a
liftLogic :: Logic a -> App a
liftLogic l = do
c <- asks appEnvLogic
either (throwError . AppLogicError) pure $ runLogic c l
使用这种方法,我如何给模块一个内部状态?如果我将StateT LogicState 放入Logic 变压器,那么liftMonad 不会完全运行monad,从而解开它并破坏它的内部状态?
我看到的唯一方法是将Logic 的内部状态泄露给App,我认为这是反模块化,因为它迫使App 处理Logic 的状态。
【问题讨论】:
-
我认为在这里更具体地了解细节会有所帮助。也许您可以在代码中勾勒出您正在考虑的内容,给出一些假设的类型签名以及您看到问题浮出水面的方式。
-
我想stackoverflow.com/questions/4785379/… 是我在这里要问的。我喜欢这个问题的答案。
标签: haskell monads monad-transformers