有状态循环与不同类型的休息 [英] Stateful loop with different types of breaks

查看:130
本文介绍了有状态循环与不同类型的休息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  while(true){
while (get()){
if(put1()){
failImmediately();


if(put2()){
succeedImmediately();


put1 put2 读取系统状态并修改它。 get 可以简单地只读状态。 failImmediately 应该跳出无限循环并提供一种类型的结果, succeedImmediately 也应该突破,不同的结果。

我尝试使用的是 State Env Result 其中 Env code>表示环境状态, Result 类似于或者失败成功对于某些自定义失败成功



我需要整体结果表达式应该在它们中的一个被生成(打破循环)并且以其他方式继续前进时折叠成失败 / 成功

我的一个想法是使用 Exit()其中数据Exit = Success |失败并使用 StateT 以某种方式在 Left 或者就好像或者是被链接的monad,即忽略任何后续动作。



我真的很感激任何灵感或Haskell代码样本,它们可以达到与上面代码片段相同的行为。



编辑:精炼版本已移动到一个单独的问题有状态的计算与不同类型的短-circuit(Maybe,Either)

解决方案

使用@ chi的答案套件,只是强调你不需要 ContT 的全部功能, EitherT 就足够了:

  import Control.Monad .Trans.Eithe r 

数据结果a =失败|成功a

foo :: EitherT(Result Int)IO Int
foo =永远$ do
whileM获得$ do
whenM put1 $ do
还剩失败
whenM put2 $ do
left $成功42

run ::(Monad m)=>或者T(结果a)m a - > m(可能是a)
run act = do
res< - runEitherT act
return $ case res
Left Failure - > Nothing
Left(Success x) - >只需x
Right x - >只需x

- 当M / whileM和get / put1 / put2根据@ chi的回答时


I am trying to convert the following stateful imperative code into Haskell.

while (true) {
  while (get()) {
    if (put1()) {
      failImmediately();
    }
  }
  if (put2()) {
    succeedImmediately();
  }
}

Both the put1 and put2 read a state of the system and modify it. get can for simplicity just read the state. failImmediately should break out of the endless-loop and present one type of result, succeedImmediately should also break out but present a different result.

What I tried to use was State Env Result where Env represented the state of environment and Result was something like Either Failure Success for some custom Failure and Success.

I struggle with the requirement that the whole resulting expression should collapse into the Failure/Success once one of them is produced (breaking the loop) and otherwise keep going.

One idea I had was use Either Exit () where data Exit = Success | Failure and use StateT somehow to behave upon Left of the Either as if Either was the monad being chained, i.e. ignoring any subsequent actions.

I would really appreciate any inspiration or sample of haskell code that would achieve the same behaviour as the snippet above.

Edit: refined version moved to a separate question "Stateful computation with different types of short-circuit (Maybe, Either)".

解决方案

Using the kit from @chi's answer, just highlighting that you don't need the full power of ContT, the direct-short-circuiting semantics of EitherT is enough:

import Control.Monad.Trans.Either

data Result a = Failure | Success a

foo :: EitherT (Result Int) IO Int
foo = forever $ do
    whileM get $ do
        whenM put1 $ do
            left Failure
    whenM put2 $ do
        left $ Success 42

run :: (Monad m) => EitherT (Result a) m a -> m (Maybe a)
run act = do
    res <- runEitherT act
    return $ case res of
        Left Failure -> Nothing
        Left (Success x) -> Just x
        Right x -> Just x

-- whenM / whileM and get/put1/put2 as per @chi's answeer

这篇关于有状态循环与不同类型的休息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆