我正在寻找一个可用于跟踪程序进度的monad变换器.要解释如何使用它,请考虑以下代码:
procedure :: ProgressT IO ()
procedure = task "Print some lines" 3 $ do
liftIO $ putStrLn "line1"
step
task "Print a complicated line" 2 $ do
liftIO $ putStr "li"
step
liftIO $ putStrLn "ne2"
step
liftIO $ putStrLn "line3"
-- Wraps an action in a task
task :: Monad m
=> String -- Name of task
-> Int -- Number of steps to complete task
-> ProgressT m a -- Action performing the task
-> ProgressT m …Run Code Online (Sandbox Code Playgroud) monads haskell functional-programming coroutine monad-transformers
对于有一些其他语言(Python/JavaScript)异步经验的人来说,在谈论 async/await 时,总是假设某处存在事件循环。但是对于 C++,我已经查看了文档并没有找到任何谈论事件循环的地方。为什么会这样?
对于 Node,它只有一个默认的事件循环。对于 Python,您可以根据需要创建多个。但是对于 C++ 来说,这个事件循环是否像 Node 一样?或者出于某种原因,我们根本不需要它吗?
我一直在python中看到很多关于协同程序的讨论和文章.它们被认为是"微线程",我听说它们可以提高性能.
协同程序如何提高性能?从我到目前为止看到的,它们是单线程并按顺序执行.我同意从设计角度来看,它们非常优雅,特别是在生产者/消费者类型的应用程序中.
我想我错过了这一点.有人可以解释一下吗?
我有一个对象的树形结构.我需要遍历叶子中的所有项目("值").为此,我目前正在使用如下所示的生成器方法:
class Node(object):
def __init__(self):
self.items = [Leaf(1), Leaf(2), Leaf(3)]
def values(self):
for item in self.items:
for value in item.values():
yield value
class Leaf(object):
def __init__(self, value):
self.value = value
def values(self):
for i in range(2):
yield self.value
n = Node()
for value in n.values():
print(value)
Run Code Online (Sandbox Code Playgroud)
这打印:
1
1
2
2
3
3
Run Code Online (Sandbox Code Playgroud)
现在,a返回的值Leaf将取决于外部参数.我正在考虑使用协程能够将此参数传递给叶节点:
import itertools
class Node2(object):
def __init__(self):
self.items = [Leaf2(1), Leaf2(2), Leaf2(3)]
def values(self):
parameter = yield
for item in self.items:
item_values = item.values()
next(item_values) …Run Code Online (Sandbox Code Playgroud) 所以我认为我理解c#yield return与pythons yield大致相同,我认为我理解.我认为编译器将一个函数转换为一个对象,该对象带有一个指向执行应该恢复的位置的指针,当对象的下一个值的请求运行到下一个yield时,它会更新指针的恢复执行位置并返回一个值.
在python中,它的工作方式类似于延迟评估,因为它根据需要生成值,但是一旦使用了值,如果不保存在另一个变量中,则可以使用gc.尝试迭代这样一个函数的结果两次返回一个空的iterable,除非你将它转换为一个列表.
恩.
def y():
list = [1,2,3,4]
for i in list:
yield str(i)
ys = y()
print "first ys:"
print ",".join(ys)
print "second ys:"
print ",".join(ys)
Run Code Online (Sandbox Code Playgroud)
输出
first ys:
1,2,3,4
second ys:
Run Code Online (Sandbox Code Playgroud)
直到最近我才认为c#也是如此,但在dotnetfiddle中尝试失败了.
http://dotnetfiddle.net/W5Cbv6
using System;
using System.Linq;
using System.Collections.Generic;
public class Program
{
public static IEnumerable<string> Y()
{
var list = new List<string> {"1","2","3","4","5"};
foreach(var i in list)
{
yield return i;
}
}
public static void Main()
{
var ys = Y();
Console.WriteLine("first ys");
Console.WriteLine(string.Join(",", …Run Code Online (Sandbox Code Playgroud) 对于在Lua协程的支持是由提供的功能在coroutine表,主要是create,resume和yield.开发人员将这些协同程序描述为堆栈,一流和非对称.
协程也可在Python,或者使用增强发电机(和yield from)或在3.5版本中增加,async和await.
Python中的协程如何与Lua中的协程相比?它们是堆叠的,一流的还是不对称的?
为什么Python的需要如此多的结构(async def,async with,async for,异步内涵,...)的协同程序,而Lua中能为他们提供只有三个内建的功能呢?
当实现在同步和异步应用程序中都有用的类时,我发现自己在两个用例中维护着几乎相同的代码。
仅作为示例,请考虑:
from time import sleep
import asyncio
class UselessExample:
def __init__(self, delay):
self.delay = delay
async def a_ticker(self, to):
for i in range(to):
yield i
await asyncio.sleep(self.delay)
def ticker(self, to):
for i in range(to):
yield i
sleep(self.delay)
def func(ue):
for value in ue.ticker(5):
print(value)
async def a_func(ue):
async for value in ue.a_ticker(5):
print(value)
def main():
ue = UselessExample(1)
func(ue)
loop = asyncio.get_event_loop()
loop.run_until_complete(a_func(ue))
if __name__ == '__main__':
main()
Run Code Online (Sandbox Code Playgroud)
在此示例中,还算不错,串联的ticker方法UselessExample易于维护,但是您可以想象异常处理和更复杂的功能可以迅速增加方法并使之成为问题,即使这两种方法实际上都可以保留下来相同(仅将某些元素替换为它们的异步对应元素)。
假设没有什么实质性差异值得完全实现,那么维护这样的类并避免不必要的重复的最佳方法(也是最Pythonic的)是什么?
目前的Boost 1.55实现提供了两种单向协同程序.一个是pull-type,它是一个不带参数的协程并将值返回给主上下文; 另一种是push-type,它是一个从主要上下文接受参数但没有返回值的协程.
如何组合这两个来创建一个双向协程,它既接受参数又返回一个值?从表面上看似乎应该是可能的,但我无法弄清楚如何使用我所拥有的构建块来实现它boost::coroutine.在旧的Boosts中曾经有过双向协程,但它现在已被弃用且没有文档,因此我不应该依赖它.
即,我想要一些类似于此的东西:
void accumulate( pull_func &in, push_func &out )
{
int x = 0;
while ( in )
{
x += in.get() ; // transfers control from main context
out(x); // yields control to main context
}
}
void caller( int n )
{
bidirectional_coro( accumulate );
for ( int i = 0 ; i < n ; ++i )
{
int y = accumulate(i);
printf( "%d ", y ); // "0 1 …Run Code Online (Sandbox Code Playgroud) 我试图使用Bluebird的协同程序如下:
var p = require('bluebird');
//this should return a promise resolved to value 'v'
var d = p.coroutine(function*(v) { yield p.resolve(v); });
//however this prints 'undefined'
d(1).then(function(v){ console.log(v); });
Run Code Online (Sandbox Code Playgroud)
这里有什么不对?