I have two similar functions which have different return types:
override def getUsers(uri: Uri): F[Either[CodecException, List[User]]] =
for {
response <- retrieveDataFromClient(uri)
result <- Sync[F].delay(response)
} yield result
override def getAnimals(uri: Uri): F[Either[CodecException, List[Animal]]] =
for {
response <- retrieveDataFromClient(uri)
result <- Sync[F].delay(response)
} yield result
And I have implicit circe
decoders for them:
implicit def decodeUser(response: HttpResponse): Either[CodecException, List[User]] = Decoder[List[User]].decode(response.entity)
implicit def decodeAnimal(response: HttpResponse): Either[CodecException, List[Animal]] = Decoder[List[Animal]].decode(response.entity)
Now I have refactored first two methods into generic one:
override def getData[A](uri: Uri): F[Either[CodecException, List[A]]] =
for {
response <- retrieveDataFromClient(uri)
result <- Sync[F].delay(response)
} yield result
And created generic circe
decoder:
implicit def decodeGeneric[A](response: HttpResponse): Either[CodecException, List[A]] = Decoder[List[A]].decode(response.entity)
But I got compilation error:
Could not find an instance of Decoder for List[A]
implicit def decodeGeneric[A](response: HttpResponse): Either[CodecException, List[A]] = Decoder[List[A]].decode(response.entity)
not enough arguments for method apply: (implicit instance: hammock.Decoder[List[A]])hammock.Decoder[List[A]] in object Decoder.
Unspecified value parameter instance.
implicit def decodeGeneric[A](response: HttpResponse): Either[CodecException, List[A]] = Decoder[List[A]].decode(response.entity)
Method retrieveDataFromClient
return F[HttpResponse]
from http client Hammock
and response is implicit parsed into type User
and Animal
(via above decoders and works fine), but now I want to have it generic to remove boilerplate.
Is it possible to refactor this code in this way and create generic decoder?