Ограничение типа означает, что функцию можно использовать для возврата значения для любого типа m
, который имеет экземпляр MonadIO
. Как правило, это означает IO
сам или стек монад, построенный поверх IO
.
Значение, возвращаемое 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
применяется к , что для получения значения типа Config.KafkaP (Either KafkaError ())
. Обратите внимание, что закомментированная строка -- forM_ err print
- это единственное, что могло бы использовать значение, полученное из produceMessage
, поэтому сейчас messageSender
делает вид, что produceMessage
сработало, независимо от того, работало оно или нет.
Более надежное определение на самом деле будет использовать возвращаемое значение produceMessage
, например,
err <- produceMessage prod message
return $ case err of
Nothing -> Right ()
Just theError -> Left theError