问题描述
我有此代码:
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,Some(ModelContract("ModelName",Some(ModelSignature("infer",Seq(ModelField(name="blah",profile=DataProfileType.NUMERICAL)),Seq.empty[ModelField])))),"",None)
Monad[F].pure(mv)
}
}
我正在尝试这样做:
val model = modelDataService.getModelVersion(modelVersionId)
val batchSize = model.monitoringConfiguration
我收到一个编译错误
value monitoringConfiguration is not a member of type parameter F[a.grpc.entities.ModelVersion]
但是,a.grpc.entities.ModelVersion
具有monitoringConfiguration
字段。我想这与F
有关。有什么方法可以访问batchSize
内部的model
?
解决方法
这取决于您对类型较高的类型F
的约束。如果您的F
是函子,则可以使用map
访问内部的值。如果F
是FlatMap
或Monad
,也可以使用flatMap
。
val batchSize: F[Long] =
modelDataService
.getModelVersion(modelVersionId)
.map(_.monitoringConfiguration)
程序的结构方式是,您的价值将始终在F
内,直到您真正需要将其取出为止。这是通过将F
初始化为某种具体类型来完成的,例如IO
来自cats-effect,或Future
来自本地scala库。或者,如果您不执行任何副作用,则可以像Option
那样简单。一旦确定了具体的类型,就可以根据类型使用不同的方法来获取价值。对于Future
可以是.onComplete
,对于Option
可以是.getOrElse
,等等。
val service: ModelDataService[Option] = new ModelDataServiceIdInterpreter[Option]
val maybeBatchSize: Option[Long] =
modelDataService
.getModelVersion(modelVersionId)
.map(_.monitoringConfiguration)
val batchSizeDefaultValue = 10L
val batchSize = maybeBatchSize.getOrElse(batchSizeDefaultValue)