这是foldM的情况吗? [英] Is this a case for foldM?

查看:78
本文介绍了这是foldM的情况吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  sendrecv :: Socket  - > 
PSQ.PSQ(字符串,整数)POSIXTime - >
Map.Map(String,Integer)[String] - >
字符串 - >
IO(PSQ.PSQ(String,Integer)POSIXTime,Map.Map(String,Integer)[String])

它需要一个套接字,一个PSQ,一个Map和一个String,并返回一个PSQ和一个Map。



我想称之为n次,其中套接字和字符串保持不变,但PSQ和Map被修改,意味着修改过的PSQ,Map应该成为下次运行的输入。



原来我认为这可能是一个完美的案例,并尝试过(q',m')< - foldM sendrecv(s,q1,m1,ping)(enumFromTo 1 1000)

但显然这不起作用,我担心我还没有理解整件事情或者是否有可能传递静态参数(如s和ping)以及如何传递。

解决方案

如果你定义了辅助函数,那么

  iterateM :: Monad m => Int  - > (a  - > m a) - > a  - > m a 
iterateM 0 _ x = return x
iterateM n f x = iterateM(n-1)f =< fx
$ b $ sendRecv'套接字字符串(q,m)= sendRecv套接字qm字符串



<那么你可以写出:

 (q',m')< -  iterateM 1000(sendRecv的ping) (q1,m1)

(我有些惊讶,像 iterateM )



话虽如此,以下是如何使用 foldM

 (q',m')< -  foldM(flip.const $ sendRecv的ping) (q1,m1)[1..1000] 


$ (q 1,m 1)[q 1,m 1](其中,b 1,b 2,..., 1..1000]

但我不认为使用 foldM 在这里设置清晰的代码。


The function sendrecv has the following type signature:

sendrecv :: Socket ->
            PSQ.PSQ (String, Integer) POSIXTime ->
            Map.Map (String, Integer) [String] ->
            String ->
            IO  (PSQ.PSQ (String, Integer) POSIXTime,  Map.Map (String, Integer) [String]) 

It takes a socket, a PSQ, a Map and a String and returns a PSQ and a Map.

I would like to call it n times where the socket and the string stay the same but the PSQ and Map get modified, means the modified PSQ, Map should become the input in the next run.

Originally I thought that this may be a perfect case for foldM and tried e.g.

(q', m') <- foldM sendrecv (s, q1, m1, "ping") (enumFromTo 1 1000)

But apparently this does not work and I fear that I have not yet understood the whole foldM thing or whether there may be a possibility to pass static parameters as well (as with s and "ping") and how.

解决方案

If you define helper functions

iterateM :: Monad m => Int -> (a -> m a) -> a -> m a
iterateM 0 _ x = return x
iterateM n f x = iterateM (n - 1) f =<< f x

sendRecv' socket string (q, m) = sendRecv socket q m string

then you can write

(q', m') <- iterateM 1000 (sendRecv' s "ping") (q1, m1)

(I'm mildly surprised that something like iterateM isn't standard.)

Having said that, here's how to do it using foldM:

(q', m') <- foldM (flip . const $ sendRecv' s "ping") (q1, m1) [1..1000]

or

(q', m') <- foldM (\(q, m) _ -> sendRecv s q m "ping") (q1, m1) [1..1000]

But I don't think using foldM here makes for clear code.

这篇关于这是foldM的情况吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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