2

我试图弄清楚我可以通过哪种方式在卤素组件包含的单子上使用变压器。

我想通过带有 Config 记录的 ReaderT 扩展介绍示例,在这种情况下,可以使用它来使字符串可配置,但是在将它们放在一起时我迷失了。

假设我们这样定义我们的 Config:

-- | Global configuration
newtype Config = Config { toggleText :: String
                        , onText :: String
                        , offText :: String
                        }

然后我们的ui函数将从

forall m eff. (Monad m) => Component m Input Input

forall m (Monad m) => Component (ReaderT Config m) Input Input.

为了评估我们的 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 上下文中,但我什至不确定这是否可能。

如果有人可以指导我了解这里的类型并告诉我这种通用方法是否明智,那就太好了。GitHub 上有一个完整的(非编译)示例。I18n 应仅作为此处阅读器的简单示例使用。

4

1 回答 1

3

monadm是事件处理程序的 monad。文档本身将HTML无权访问您的Readermonad 中的配置。

Reader如果您希望您的事件处理程序能够访问某些配置对象,您将使用,并且您必须将使用替换为monad中A.input_的操作。Reader

为了做你想做的事,你可能想要更像MonadReader Config m => m (Component _ _ _),其中组件本身取决于配置。

于 2015-06-04T18:28:22.740 回答