本文介绍了哈斯克尔相当于C#5异步/的await的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我刚刚看了一下新的方式使用等待和异步关键字来处理在C#5.0异步函数。 〔实施例从在 C#参考的await :I just read about the new way to handle asynchronous functions in C# 5.0 using the await and async keywords. Examle from the C# reference on await:private async Task SumPageSizesAsync(){ // To use the HttpClient type in desktop apps, you must include a using directive and add a // reference for the System.Net.Http namespace. HttpClient client = new HttpClient(); // . . . Task<byte[]> getContentsTask = client.GetByteArrayAsync(url); byte[] urlContents = await getContentsTask; // Equivalently, now that you see how it works, you can write the same thing in a single line. //byte[] urlContents = await client.GetByteArrayAsync(url); // . . .} A 任务&LT;字节[]&GT; 重新presents异步任务的未来,将产生类型的值字节[ ] 。使用关键字等待在工作将基本上把函数的休息,这将被称为续当任务完成。任何使用功能等待必须使用关键字异步并键入任务&LT; A&GT; 是否会返回一个类型 A 。A Task<byte[]> represents the Future of an asynchronous task that will generate a value of type byte[]. Using the keyword await on a Task will basically put the rest of the function in a continuation which will be called when the task is done. Any function that uses await must use the keyword async and have type Task<a> if it would return type a.因此,行byte[] urlContents = await getContentsTask;// Do something with urlContents将转化为类似Task newTask = getContentsTask.registerContinuation( byte[] urlContents => { // Do something with urlContents });return newTask;这感觉很像一个单子( - 变压器?)。这感觉就像它应该有一些关系到CPS单子,但也许不是。This feels a lot like a Monad (-transformer?). It feels like it shouldhave some relation to the CPS monad, but maybe not.这是我在写作相应的哈斯克尔类型的尝试Here is my attempt at writing corresponding Haskell types-- The monad that async functions should run ininstance Monad Async-- The same as the the C# keywordawait :: Async (Task a) -> Async a-- Returns the current Task, should wrap what corresponds to-- a async method in C#.asyncFunction :: Async a -> Async (Task a)-- Corresponds to the method Task.Run()taskRun :: a -> Task a和上述实施例的一个粗略的翻译and a rough translation of the above exampleinstance MonadIO Async -- Needed for this examplesumPageSizesAsync :: Async (Task ())sumPageSizesAsync = asyncFunction $ do client <- liftIO newHttpClient -- client :: HttpClient -- ... getContentsTask <- getByteArrayAsync client url -- getContentsTask :: Task [byte] urlContents <- await getContentsTask -- urlContents :: [byte] -- ...这将是在Haskell相应的类型?是否有任何哈斯克尔库本(或类似方式)实现的方式来处理异步函数/动作?Would this be the corresponding types in Haskell? Is there any Haskell library this (or a similar way) implements way to handle asynchronous functions/actions?另外:你能建立这个使用CPS变压器Also: Could you build this using the CPS-transformer?是的, Control.Concurrent.Async 模块确实解决类似的问题(和具有类似的接口),但在一个完全不同的方式这样做。我想这 Control.Monad.Task 将是一个更匹配。什么(我认为)我期待的是期货一元界面的使用延续传递风格幕后推荐答案下面是建立在异步工作单子C $ C>库:Here's a Task monad that builds on top of the async library:import Control.Concurrent.Async (async, wait)newtype Task a = Task { fork :: IO (IO a) }newTask :: IO a -> Task anewTask io = Task $ do w <- async io return (wait w)instance Monad Task where return a = Task $ return (return a) m >>= f = newTask $ do aFut <- fork m a <- aFut bFut <- fork (f a) bFut请注意,我没有检查这个单子的法律,所以它可能是不正确的。Note that I haven't checked the monad laws for this, so it might not be correct.这是你将如何定义在后台运行的基本任务:This is how you would define primitive tasks that run in the background:import Control.Concurrent (threadDelay)test1 :: Task Inttest1 = newTask $ do threadDelay 1000000 -- Wait 1 second putStrLn "Hello," return 1test2 :: Task Inttest2 = newTask $ do threadDelay 1000000 putStrLn " world!" return 2然后你可以将任务■哪些创建一个新的递延任务准备就绪,可以运行使用不要标记:Then you can combine Tasks using do notation which creates a new deferred task ready to be run:test3 :: Task Inttest3 = do n1 <- test1 n2 <- test2 return (n1 + n2)运行叉TEST3 将酿出工作并返回未来,你可以随时调用要求的因此,如果必要则阻塞,直到完成。Running fork test3 will spawn the Task and return a future which you can invoke at any time to demand the result, blocking if necessary until done.要表明它的作品,我会做两个简单的测试。首先,我将叉 TEST3 而不苛求其未来只是为了确保它正确派生复合螺纹:To show that it works, I'll do two simple tests. First, I'll fork test3 without demanding its future just to make sure it spawns the composite thread correctly:main = do fork test3 getLine -- wait without demanding the future这正常工作:$ ./taskHello, world!<Enter>$现在我们可以测试我们的需求,结果会发生什么:Now we can test what happens when we demand the result:main = do fut <- fork test3 n <- fut -- block until 'test3' is done print n ...这也可以工作:... which also works:$ ./taskHello, world!3$ 这篇关于哈斯克尔相当于C#5异步/的await的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云! 08-04 08:22