用于卤素组分的Monad变压器

时间:2015-06-04 16:29:18

标签: monad-transformers purescript halogen

我正在试图弄清楚我可以在Halogen组件所包含的monad上使用变换器。

我想通过带有Config记录的ReaderT扩展intro example,在这种情况下可以用来使字符串可配置,但是当我把它放在一起时我很遗憾

假设我们像这样定义我们的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

为了评估我们的主要功能,我们然后使用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的简单示例。

1 个答案:

答案 0 :(得分:3)

monad m是事件处理程序的monad。 HTML文档本身无法访问Reader monad中的配置。

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

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