具有与预期不同签名的传递函数
Pass function with different signature than is expected
我在消息消费控制台应用程序中使用 AMQP library for Haskell。我正在绑定这样的消息处理程序:
consumeMsgs ch "tasks" Ack taskHandler
我的问题是 consumeMsgs
需要一个具有此签名的消息处理程序:
taskHandler :: (Message, Envelope) -> IO ()
...但我需要传递额外的 Channel
和 Lock
(Channel
以便我可以将结果发布到不同的队列,Lock
用于打印到控制台),像这样:
taskHandler :: (Message, Envelope) -> Channel -> MVar () -> IO ()
我来自 Javascript 土地,但我不希望像全局变量这样的肮脏解决方案。这里可以做什么?
我不太清楚你的限制,但如果你在 consumeMsgs
调用站点上有你需要的东西,你可以使用闭包。 (我假设 ch
是你想要的频道)
lock <- ...
consumeMsgs ch "tasks" Ack (\(msg,env) -> taskHandler (msg,env) ch lock)
(不一定非要在元组(msg,env)
上匹配,因为直接用了,这只是我能想到的最好的名字)
如果将参数的顺序更改为 taskHandler
,您可以获得非常惯用的 Haskell 部分应用解决方案:
taskHandler :: Channel -> MVar () -> (Message, Envelope) -> IO ()
...
consumeMsgs ch "tasks" Ack (taskHandler ch lock)
这是部分应用程序的用武之地。
如果将参数的顺序更改为
taskHandler :: Channel -> MVar () -> (Message, Envelope) -> IO ()
然后您可以将 taskHandler
部分应用到 Channel
和 MVar ()
,即 taskHandler channel mvar
。这将 return 一个新函数,它正是 consumeMsgs
期望的类型。
我在消息消费控制台应用程序中使用 AMQP library for Haskell。我正在绑定这样的消息处理程序:
consumeMsgs ch "tasks" Ack taskHandler
我的问题是 consumeMsgs
需要一个具有此签名的消息处理程序:
taskHandler :: (Message, Envelope) -> IO ()
...但我需要传递额外的 Channel
和 Lock
(Channel
以便我可以将结果发布到不同的队列,Lock
用于打印到控制台),像这样:
taskHandler :: (Message, Envelope) -> Channel -> MVar () -> IO ()
我来自 Javascript 土地,但我不希望像全局变量这样的肮脏解决方案。这里可以做什么?
我不太清楚你的限制,但如果你在 consumeMsgs
调用站点上有你需要的东西,你可以使用闭包。 (我假设 ch
是你想要的频道)
lock <- ...
consumeMsgs ch "tasks" Ack (\(msg,env) -> taskHandler (msg,env) ch lock)
(不一定非要在元组(msg,env)
上匹配,因为直接用了,这只是我能想到的最好的名字)
如果将参数的顺序更改为 taskHandler
,您可以获得非常惯用的 Haskell 部分应用解决方案:
taskHandler :: Channel -> MVar () -> (Message, Envelope) -> IO ()
...
consumeMsgs ch "tasks" Ack (taskHandler ch lock)
这是部分应用程序的用武之地。
如果将参数的顺序更改为
taskHandler :: Channel -> MVar () -> (Message, Envelope) -> IO ()
然后您可以将 taskHandler
部分应用到 Channel
和 MVar ()
,即 taskHandler channel mvar
。这将 return 一个新函数,它正是 consumeMsgs
期望的类型。