我有一个函数,该函数返回包裹在Monad中的值,
produceMessage :: MonadIO m => KafkaProducer -> ProducerRecord -> m (Maybe KafkaError)
我有一些代码可以像这样
来调用此函数err <- produceMessage prod message
return $ Right ()
上面的代码是别人写的,我只是想了解这里发生的事情。这是其余的功能
messageSender :: KafkaProducer -> String -> Config.KafkaP (Either KafkaError ())
messageSender prod msg = do
message <- mkMessage Nothing (Just $ pack msg)
err <- produceMessage prod message
--forM_ err print
return $ Right ()
我有三个具体问题,
我很困惑produceMessage
的类型签名是什么意思?类型约束为MonadIO m
,这是什么意思?
返回类型为m (Maybe KafkaError)
,因此此返回的Maybe
值包装在哪个monad中?
Right ()
在这里如何出现?总的来说我真的不是
能够理解messageSender
的最后两行。
答案 0 :(得分:6)
类型约束意味着该函数可用于返回具有m
实例的任何类型MonadIO
的值。通常,这意味着IO
本身或在IO
之上构建的monad堆栈。
produceMessage
返回的值部分由调用者确定。需要一个IO (Maybe KafkaError)
值吗?您可以得到它,因为IO
有一个MonadIO
实例。需要MyCustomMonadStack (Maybe KafkaError)
吗?如果为MonadIO
定义了一个MyCustomMonadStack
实例,就可以得到。
根据Config.KafkaP
使用MonadIO
的方式,messageSender
大概也有一个produceMessage
实例。
messageSender
的返回值为Config.KafkaP (Either KafkaError ())
。表达式return $ Right ()
首先使用Right ()
产生类型Either KafkaError ()
的值,然后将return
应用于那个以产生类型{ {1}}。请注意,注释行Config.KafkaP (Either KafkaError ())
是唯一使用来自-- forM_ err print
的值的东西,所以现在produceMessage
冒充messageSender
有效,无论是否有效
更健壮的定义实际上将以某种方式使用produceMessage
的返回值,例如
produceMessage