我试图弄清楚如何在 Halogen 的 monad 上使用变压器。组件包含。
我想延长 intro example由带有配置记录的 ReaderT 提供,在本例中,该记录可用于使字符串可配置,但当将它们放在一起时,我迷失了方向。
假设我们这样定义我们的配置:
-- | Global configuration
newtype Config = Config { toggleText :: String
, onText :: String
, offText :: String
}
我们的 ui
函数将从
forall m eff。 (Monad m) => 组件 m 输入 输入
至
forall m (Monad m) => 组件 (ReaderT Config m) 输入输入
。
为了评估我们的 main 函数,我们将使用 hoistComponent
将其恢复为之前的形式:
main = do
let config = Config { toggleText: "Toggle Button"
, onText: "On"
, offText: "Off"
}
Tuple node _ <- runUI $ hoistComponent (runReaderT config) ui
appendToBody node
到目前为止,我不确定这是否有意义,但假装它有意义,下一步就是我正在努力的地方。在理想的世界中,我的 ui 功能将允许我做这样的事情:
ui :: forall m eff. (Monad m) => Component (ReaderT Config m) Input Input
ui = render <$> stateful (State { on: false }) update
where
render :: State -> H.HTML (ReaderT Config m Input)
render (State s) = do
(Config conf) <- ask
return $ H.div_ [ H.h1_ [ H.text conf.toggleText ]
, H.button [ A.onClick (A.input_ ToggleState) ]
[ H.text (if s.on then conf.onText else conf.offText) ]
]
update :: State -> Input -> State
update (State s) ToggleState = State { on: not s.on }
但我最终遇到了一长串统一错误,并且不知道从哪里开始。显然,ask
的内部使用不能像这样工作,因为我需要将它提升到 HTML 上下文中,但我什至不确定这是否可能。
如果有人可以指导我了解这里的类型并告诉我这种一般方法是否合理,那就太好了。完整(非编译)示例是 on GitHub 。 I18n 在此仅应作为 Reader 的简单使用示例。
最佳答案
monad m
是事件处理程序的 monad。 HTML
文档本身无法访问 Reader
monad 中的配置。
如果您希望事件处理程序能够访问某些配置对象,则可以使用 Reader
,并且您必须将 A.input_
的使用替换为操作在 Reader
monad 中。
要完成您想做的事情,您可能需要类似于 MonadReader Config m => m (Component _ _ _)
的东西,其中组件本身取决于配置。
关于monad-transformers - 用于卤素元件的 Monad 变压器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30649310/