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

问题描述 投票:0回答:1

我有一些代码从队列中读取数据。我希望函数能够将回调函数作为参数,回调函数基本上包含有关如何处理从队列中提取的数据的代码。 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 ()

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

haskell typeclass monad-transformers
1个回答
0
投票

您可以在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)

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

© www.soinside.com 2019 - 2024. All rights reserved.