여기에서 튜토리얼을 수행하고 있습니다 (http://typelevel.org/cats/datatypes/freemonad.html). 키 값 저장소 앞에있는 캐시에서 작동하도록 수정하려고합니다. 이것이 내가 지금까지 생각해 왔지만 valueGetOperation
과 컴파일러 오류가 발생했습니다. 내가 왜 컴파일 오류가 나는지 이해할 수 없다. 나는 그 문제를 해결하는 방법을 모른다. 무료 모나드를 사용할 때 조건부 동작에 대한 가장 좋은 방법은 무엇입니까? 당신이 for
이해에 알다시피무료 모나드를 사용한 조건부 동작
import cats.data.Coproduct
import cats.free.{Free, Inject}
object KvStore {
sealed trait KvOp[A]
case class Get[T](key: String) extends KvOp[Option[T]]
case class Put[T](key: String, value: T) extends KvOp[Unit]
case class Delete[T](key: String) extends KvOp[Unit]
}
object CacheStore {
sealed trait CacheOp[A]
case class Get[T](key: String) extends CacheOp[Option[T]]
case class Put[T](key: String, value: T) extends CacheOp[Unit]
case class Delete[T](key: String) extends CacheOp[Unit]
}
type WriteThruCache[A] = Coproduct[KvStore.KvOp, CacheStore.CacheOp, A]
class KvOps[F[_]](implicit I: Inject[KvStore.KvOp, F]) {
import KvStore._
def get[T](key: String): Free[F, Option[T]] = Free.inject[KvOp, F](Get(key))
def put[T](key: String, value: T): Free[F, Unit] = Free.inject[KvOp, F](Put(key, value))
def delete[T](key: String): Free[F, Unit] = Free.inject[KvOp, F](Delete(key))
}
object KvOps {
implicit def kvOps[F[_]](implicit I: Inject[KvStore.KvOp, F]): KvOps[F] = new KvOps[F]
}
class CacheOps[F[_]](implicit I: Inject[CacheStore.CacheOp, F]) {
import CacheStore._
def get[T](key: String): Free[F, Option[T]] = Free.inject[CacheOp, F](Get(key))
def put[T](key: String, value: T): Free[F, Unit] = Free.inject[CacheOp, F](Put(key, value))
def delete[T](key: String): Free[F, Unit] = Free.inject[CacheOp, F](Delete(key))
}
object CacheOps {
implicit def cacheOps[F[_]](implicit I: Inject[CacheStore.CacheOp, F]): CacheOps[F] = new CacheOps[F]
}
def valueWriteOperation[T](implicit Kv: KvOps[WriteThruCache], Cache: CacheOps[WriteThruCache]): ((String, T) => Free[WriteThruCache, Unit]) = {
(key: String, value: T) =>
for {
_ <- Kv.put(key, value)
_ <- Cache.put(key, value)
} yield()
}
// This is where I'm stuck
// desired behavior: If the value isn't in the cache, load it from the kv store and put it in the cache
def valueGetOperation[T](implicit Kv: KvOps[WriteThruCache], Cache: CacheOps[WriteThruCache]): ((String) => Free[WriteThruCache, Option[T]]) = {
(key: String) =>
for {
cacheOption <- Cache.get[T](key)
kvOption <- Kv.get[T](key) if cacheOption.isEmpty // value withFilter is not a member of cats.free.Free[A$A39.this.WriteThruCache,Option[T]]
} yield cacheOption.orElse(kvOption)
}
감사합니다. if/else보다 더 "기능적인"방법을 원했지만 올바르게 작동합니다. – Mike