在 Haskell 中使用 monad 转换器 RWST
Working with monad transformer RWST in Haskell
我在 Haskell 项目中使用 monad 转换器 RWST。下面是我的源代码:
type HSL a = RWST HBConfig [HBLog] a IO a
runScript :: (HLanguage a, BuilderHSL a)
=> HBConfig
-> HSL a
-> String
runScript hbConf srcHSL =
unsafePerformIO $ do
(_, s, log) <- runRWST srcHSL hbConf initHLang
return $ buildHSL hbConf s
我实现了函数HSL HLangJS -> HLangJS
,如下所示:
ujs :: HSL HLangJS -> HLangJS
ujs srcHSL =
unsafePerformIO $ do
(a, s, log) <- runRWST srcHSL defaultHBConfig HLangJS
return a
一切正常。但!!!我敢肯定这不是最好的解决方案!
必须从转换器请求配置和日志,如以下代码所示:
ujs :: HSL a -> a
ujs rws =
unsafePerformIO $ liftIO $ do
c <- ask
s <- get
(a, _, _) <- runRWST rws c s
return a
但是这段代码不起作用!我该如何实施?
首先,我觉得你的HSL
类型可能更好一些。 HSL
是 monad 但你限制了它。状态类型和 monad "value" 类型可能不同。您可以随时限制它们。
type HSL l a = RWST HBConfig [HBLog] l IO a
或更好:
type HSL l = RWST HBConfig [HBLog] l IO
其次,您的 HSL
monad 只能使用配置和初始状态的默认值进行转换 HSL l a -> l
。如果你想隐藏这个参数,你应该想想你可以从哪里得到它们?例如,你可以从 IO:
ujs :: HSL l a -> IO l
ujs act = do
config <- ...
initState <- ...
fst <$> execRWST act config initState
我在 Haskell 项目中使用 monad 转换器 RWST。下面是我的源代码:
type HSL a = RWST HBConfig [HBLog] a IO a
runScript :: (HLanguage a, BuilderHSL a)
=> HBConfig
-> HSL a
-> String
runScript hbConf srcHSL =
unsafePerformIO $ do
(_, s, log) <- runRWST srcHSL hbConf initHLang
return $ buildHSL hbConf s
我实现了函数HSL HLangJS -> HLangJS
,如下所示:
ujs :: HSL HLangJS -> HLangJS
ujs srcHSL =
unsafePerformIO $ do
(a, s, log) <- runRWST srcHSL defaultHBConfig HLangJS
return a
一切正常。但!!!我敢肯定这不是最好的解决方案! 必须从转换器请求配置和日志,如以下代码所示:
ujs :: HSL a -> a
ujs rws =
unsafePerformIO $ liftIO $ do
c <- ask
s <- get
(a, _, _) <- runRWST rws c s
return a
但是这段代码不起作用!我该如何实施?
首先,我觉得你的HSL
类型可能更好一些。 HSL
是 monad 但你限制了它。状态类型和 monad "value" 类型可能不同。您可以随时限制它们。
type HSL l a = RWST HBConfig [HBLog] l IO a
或更好:
type HSL l = RWST HBConfig [HBLog] l IO
其次,您的 HSL
monad 只能使用配置和初始状态的默认值进行转换 HSL l a -> l
。如果你想隐藏这个参数,你应该想想你可以从哪里得到它们?例如,你可以从 IO:
ujs :: HSL l a -> IO l
ujs act = do
config <- ...
initState <- ...
fst <$> execRWST act config initState