如何处理单价返回值m(也许是Foo)?

时间:2019-03-22 19:03:27

标签: haskell monads

我有一个函数,该函数返回包裹在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 ()

我有三个具体问题,

  1. 我很困惑produceMessage的类型签名是什么意思?类型约束为MonadIO m,这是什么意思?

  2. 返回类型为m (Maybe KafkaError),因此此返回的Maybe值包装在哪个monad中?

  3. Right ()在这里如何出现?总的来说我真的不是 能够理解messageSender的最后两行。

1 个答案:

答案 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