저는 프로젝트에서 무료 모나드를 사용하기 시작했습니다. 저는 그것을 우아하게 만들기 위해 고심하고 있습니다.
두 문맥 (실제로는 더 있습니다) - Receipt
및 User
- 둘 다 데이터베이스에 대한 작업이 있으며, 나는 그들의 통역사를 별도로 유지하고 마지막 순간에 작성하고 싶습니다.
각기 다른 작업을 정의하고 Coproduct
을 사용하여 하나의 유형으로 결합해야합니다.
나는 인터넷 검색 및 읽기의 일 후에 무슨이이다 : 나는이 작업을 수행 할 수있는 프로그램을 작성하려는 경우스칼라 무료 모나드 (Copadduct)와 모나드 변환기 (monad transformer)
// Receipts
sealed trait ReceiptOp[A]
case class GetReceipt(id: String) extends ReceiptOp[Either[Error, ReceiptEntity]]
class ReceiptOps[F[_]](implicit I: Inject[ReceiptOp, F]) {
def getReceipt(id: String): Free[F, Either[Error, ReceiptEntity]] = Free.inject[ReceiptOp, F](GetReceipt(id))
}
object ReceiptOps {
implicit def receiptOps[F[_]](implicit I: Inject[ReceiptOp, F]): ReceiptOps[F] = new ReceiptOps[F]
}
// Users
sealed trait UserOp[A]
case class GetUser(id: String) extends UserOp[Either[Error, User]]
class UserOps[F[_]](implicit I: Inject[UserOp, F]) {
def getUser(id: String): Free[F, Either[Error, User]] = Free.inject[UserOp, F](GetUser(id))
}
object UserOps {
implicit def userOps[F[_]](implicit I: Inject[UserOp, F]): UserOps[F] = new UserOps[F]
}
:
type ReceiptsApp[A] = Coproduct[ReceiptOp, UserOp, A]
type Program[A] = Free[ReceiptsApp, A]
def program(implicit RO: ReceiptOps[ReceiptsApp], UO: UserOps[ReceiptsApp]): Program[String] = {
import RO._, UO._
for {
// would like to have 'User' type here
user <- getUser("user_id")
receipt <- getReceipt("test " + user.isLeft) // user type is `Either[Error, User]`
} yield "some result"
}
문제는 여기에 그 예를 user
에 대한에 이해는 유형 Either[Error, User]
이고 getUser
서명을 보면 이해할 수 있습니다.
내가 갖고 싶은 것은 User
이거나 계산이 중지되었습니다.
나는 어떻게 든 EitherT
모나드 변압기 또는 FreeT
을 사용해야한다고 알고있다. 그러나 시간을두고 노력한 후에는 작동시키기 위해 유형을 결합하는 방법을 모르고있다.
누군가 도움을 줄 수 있습니까? 자세한 내용이 필요하면 알려주십시오. 도움을 기꺼이 누군가가 그것을 실행할 수 있도록
내가 또한, 여기에 최소한의 SBT 프로젝트를 만들었습니다 https://github.com/Leonti/free-monad-experiment/blob/master/src/main/scala/example/FreeMonads.scala건배, Leonti
Freek library이 문제를 해결하기 위해 필요한 모든 기계를 구현
, 단지의 경우 클래스 인 getUser가'로'GetUser'을 정의 User]'를 호출하고 인터프리터가 오류를 처리하도록합니다. 'GetReceipt'와 유사합니다. –
@ TomasMikula하지만 프로그램 내부에서 오류를 처리하고 싶습니다. 자동으로 처리되기를 원합니다. 이 기사를 보시기 바랍니다 : https://medium.com/iterators/free-monads-in-web-stack-part-i-2955d44757b5 남자는 무료 모나드가있는 EitherT를 사용하므로, 오류 계산은 둘 중 하나를 풀지 않고 자동으로 중지됩니다. – Leonti
그래, 통역사가 그걸 처리하기를 원해. 'Free' 프로그램을 작성할 때 오류를 처리하고 싶지는 않습니다. 그 기사에는'행동'이'어느 쪽이든'을, 그리고 해석자'행동 ~> 이드'가 있습니다. 대신에,'Action'은 성공적인 결과를 리턴 할뿐 인터프리터'Action ~> [Error,?]'를 가질 수 있습니다. 최소한 사용자 쪽은 아니지만 '어느 쪽이나'는 필요하지 않습니다. 또한 인터프리터가 오류 유형을 결정하도록 남겨 둡니다. –