这是foldM的案例吗?

J F*_*sch 1 haskell

sendrecv函数具有以下类型签名:

sendrecv :: Socket ->
            PSQ.PSQ (String, Integer) POSIXTime ->
            Map.Map (String, Integer) [String] ->
            String ->
            IO  (PSQ.PSQ (String, Integer) POSIXTime,  Map.Map (String, Integer) [String]) 
Run Code Online (Sandbox Code Playgroud)

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

我想把它调用n次,其中套接字和字符串保持不变,但PSQ和Map得到修改,意味着修改后的PSQ,Map应该成为下一次运行的输入.

最初我认为这可能是foldM的完美案例,并尝试过例如

(q', m') <- foldM sendrecv (s, q1, m1, "ping") (enumFromTo 1 1000)
Run Code Online (Sandbox Code Playgroud)

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

dav*_*420 5

如果定义辅助函数

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
Run Code Online (Sandbox Code Playgroud)

然后你可以写

(q', m') <- iterateM 1000 (sendRecv' s "ping") (q1, m1)
Run Code Online (Sandbox Code Playgroud)

(我有点意外的事情,这iterateM是不标准的.)

话虽如此,这里是如何使用foldM:

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

要么

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

但我认为foldM在这里使用不会产生明确的代码.