这是foldM的案例吗?

时间:2012-02-20 16:12:31

标签: 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]) 

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

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

最初我认为这对于foldM来说可能是一个完美的例子,并尝试过例如

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

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

1 个答案:

答案 0 :(得分: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

然后你可以写

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

(我对iterateM之类的东西不标准感到有些惊讶。)

话虽如此,以下是使用foldM

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

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

但我不认为在这里使用foldM会产生清晰的代码。