具有与预期不同签名的传递函数

Pass function with different signature than is expected

我在消息消费控制台应用程序中使用 AMQP library for Haskell。我正在绑定这样的消息处理程序:

  consumeMsgs ch "tasks" Ack taskHandler

我的问题是 consumeMsgs 需要一个具有此签名的消息处理程序:

taskHandler :: (Message, Envelope) -> IO ()

...但我需要传递额外的 ChannelLockChannel 以便我可以将结果发布到不同的队列,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 部分应用到 ChannelMVar (),即 taskHandler channel mvar。这将 return 一个新函数,它正是 consumeMsgs 期望的类型。