繁体   English   中英

如何在haskell中使用泛型类型的函数

[英]How to use generic type for functions in haskell

我有一些代码从队列中读取数据。 我希望函数能够将回调函数作为参数,回调函数基本上包含有关如何处理从队列中提取的数据的代码。 getMessages功能的类型就是这样

getMessages ::  (ConsumerRecord (Maybe ByteString) (Maybe ByteString) -> Kafkamonad (Either Error Result)) -> KafkaMonad (Either Error ())

所以回调函数必须始终是类型

(ConsumerRecord (Maybe ByteString) (Maybe ByteString) -> Kafkamonad (Either Error Result))

虽然这段代码有用,但我想为get messages函数设置一个更通用的类型,比如

getmessages ::(ConsumerRecord (Maybe ByteString) (Maybe ByteString) -> Kafkamonad a) -> KafkaMonad (Either Error ())
or 
getMessages ::  f -> KafkaMonad (Either Error ())

当我尝试使用提到的类型时,就像Kafkamonad一样,它会把错误抛给我

Couldn't match type ‘a’ with ‘Either Error b0’ ‘a’ is a rigid type variable bound by the type signature for: 
getMessages :: forall a. Callback a -> KafkaMonad a at src/Kafka/Consume.hs:48:17 
Expected type: KafkaMonad (Either KafkaError b0) 
Actual type: KafkaMonad a 

相关功能如下

type Callback a = ConsumerRecord (Maybe ByteString) (Maybe ByteString) -> KafkaMonad a
getMessages ::  Callback a -> KafkaMonad a
getMessages callback = do
       let ....
       runHandler(Right kc)  = processMessages kc callback
    bracket mkConsumer clConsumer runHandler

processMessages :: Kc -> Callback a -> KafkaMonad a
processMessages k callback=     mapM_ (\_ -> do
                    ecr <- pollMessage k (Timeout 1000)
                    case ecr of
                      Right cr ->  do
                                   err <- commitAllOffsets OffsetCommit k
                                   case err of
                                        Nothing  -> callback cr
                                        Just err -> throwIO err 
                      Left err -> return $ Left $ KafkaError "Procesing Stopped"  

            ) [0 :: Integer .. ]
    return $ Right ()

我可以使用什么类的约束来实现这一目标? 或者任何其他解决方案也会很棒。

您可以在Kafkamonad包装的类型上定义参数化的类型别名:

type CallbackType a = ConsumerRecord (Maybe ByteString) (MaybeByteString) -> Kafkamonad a

然后,您也可以使用此类型定义getMesagages

getMessages :: CallbackType a -> KafkaMonad (Either Error ())

请注意,此类型注释指示getMessages的定义可以是什么; 你不能做什么任何假设a可能。 如果有任何限制(由KafkamonadgetMessages的必需定义强加),您需要在问题中指定这些限制。

根据您的错误消息,您有关于Kafkamonad包含什么类型的未声明的假设,这会阻止您完全参数化回调类型。 尝试

type CallbackType a = ConsumerRecord (Maybe ByteString) (MaybeByteString) -> Kafkamonad (Either KafkaError a)

或修改您的定义以删除假设。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM