I have this code:
trait ModelDataService[F[_]] {
def getModelVersion(modelVersionId: Long): F[ModelVersion]
}
class ModelDataServiceIdInterpreter[F[_] : Monad] extends ModelDataService[F] {
override def getModelVersion(modelVersionId: Long): F[ModelVersion] = {
val mv = ModelVersion(1, 1, "ModelType", "Status", None, None, Some(ModelContract("ModelName", Some(ModelSignature("infer", Seq(ModelField(name="blah", profile=DataProfileType.NUMERICAL)), Seq.empty[ModelField])))), None, "", None)
Monad[F].pure(mv)
}
}
I am trying to do this:
val model = modelDataService.getModelVersion(modelVersionId)
val batchSize = model.monitoringConfiguration
I get a compile error
value monitoringConfiguration is not a member of type parameter F[a.grpc.entities.ModelVersion]
However, a.grpc.entities.ModelVersion
has the monitoringConfiguration
field. I guess it has something to do with F
. Is there a way I can access the batchSize
inside model
?
It depends on constraints that you have over your higher-kinded type F
. If your F
is a functor, then you can access the value inside using map
. If F
is a FlatMap
, or a Monad
, you can also use flatMap
.
val batchSize: F[Long] =
modelDataService
.getModelVersion(modelVersionId)
.map(_.monitoringConfiguration)
The way the program is structured is that your value will be inside of F
at all times, until you really need to get it out. And that is done by initiation of F
to some concrete type, e.g. IO
from cats-effect, or Future
from native scala library. Or if you don't perform any side-effects, it can be as simple as Option
. Once the type is concrete, you have different ways of getting the value out, depending on the type. For Future
it can be .onComplete
, for Option
it can be .getOrElse
, etc.
val service: ModelDataService[Option] = new ModelDataServiceIdInterpreter[Option]
val maybeBatchSize: Option[Long] =
modelDataService
.getModelVersion(modelVersionId)
.map(_.monitoringConfiguration)
val batchSizeDefaultValue = 10L
val batchSize = maybeBatchSize.getOrElse(batchSizeDefaultValue)