在Haskell中使用monad变换器RWST

时间:2016-12-26 12:54:00

标签: haskell monad-transformers

我在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

但是这段代码不起作用!我该如何实现呢?

1 个答案:

答案 0 :(得分:2)

首先,我认为您的HSL类型可能会更好。 HSL是monad,但你限制了它。状态类型和monad“值”类型可能不同。任何时候,你都可以限制它们。

type HSL l a = RWST HBConfig [HBLog] l IO a

或更好:

type HSL l = RWST HBConfig [HBLog] l IO

其次,您的HSL monad只能使用config和初始状态的默认值进行转换HSL l a -> l。如果你想隐藏这个参数,你应该考虑一下你可以在哪里获得它们?例如,您可以从IO获取它:

ujs :: HSL l a -> IO l
ujs act = do
    config <- ...
    initState <- ...
    fst <$> execRWST act config initState