繁体   English   中英

Haskell 管道中的“产量”

[英]"Yield from" in Haskell Pipes

Haskell Pipes中,假设我正在编写f:: Producer am ()并且我在关于m的 do 块内(编辑:这没有意义;我想要一个生产者 do 块)。 在这个 do 块中,我想在返回到我的 do 块之前从g:: Producer am ()产生。 我如何做到这一点?

在我的特殊情况下, a = ()m = State s ,我的生产者正在管理一些仅影响 state.g 的分支行为g恰好只产生一次,所以在 Python 语言中,它是一个上下文管理器,它改变了一些 state,产量,然后自行清理。 因此,在 Python 中,我可以“从 g 中产生”或在g上使用@contextmanager并输入with块。

编辑:我正在寻找的是为回溯 function 编写分支,比如

do
 whenM accept_this_one (lift move_to_next)
 forM_ choices \i -> 
   when (notM (bad_choice i)) (lift (select i))

g就像select i ,因此将g视为i_type -> Producer () m ()

move_to_nextselect都像上下文管理器,自行清理。 所以 state 从move_to_next的变化应该持续到(块的末尾?在这里我很困惑。但肯定比单行更长。)这应该提供一些可以迭代的东西,它会为你管理 state。

在回答有关 state 如何受到影响的问题时, f应该合并 g 的 state 更改,如果我们说yield from g g fg可以访问公共 state,那么它会在 Python 中这样做。

Edit2:这是我想要的 Python 版本:

@contextmanager
def move_to_next():
    # do stuff
    yield
    # undo stuff
    return

@contextmanager
def selected(i):
    # do stuff
    yield
    # undo stuff
    return

if accept_this_one():
    cm = move_to_next()
else:
    cm = contextlib.nullcontext()
with cm:
    for i in choices:
        if not bad_choice(i):
            with selected(i):
                # Do stuff if you want
                yield

编辑3:也许这个?

select : i_type -> Prod () m ()
move_to_next : Prod () m ()
accept_this_one : m bool

do
 let x = ifM (lift accept_this_one)
           then move_to_next
           else yield
 x ~> \_ -> forM_ choices \i -> 
   when (notM (bad_choice i)) (select i)

yield (实际上,在这种情况下)具有类型a -> Producer am () 您不能在mdo块中使用它,只能在Producer am ()do块中使用它。 如果你需要使用一个State ,你需要先将它liftProducer

f :: Producer s (State s ()) ()
f = do
      x <- lift get
      yield x

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM