<@U5MPVGMQD> Assuming both `post` and `likesCount`...
# arrow
r
@aeruhxi Assuming both
post
and
likesCount
give you back a
Deferred<Option>
you can use here
OptionT
since really your concerns in terms of types is that you have an Option nested inside
Deferred
and that is what
OptionT
is for. Whenever
Option
is found inside a different effect, its transformer can be applied to flatten all effects through the potential absence of values nested in the computation. If any of the options happens to be a
None
`,
OptionT
will shortcircuit yielding a
DeferredK(None)
in this case.
Copy code
sealed class LikeStatus
data class LikeCount(val likes: Int) : LikeStatus
object UnknownLikes : LikeStatus

data class PostId(val value: String)
data class PosterId(val value: String)
data class PostInfo(postId: PostId, posterId: PosterId, likeStatus: LikeStatus)

fun fetchPostIds(query: Query, postId: PostId, userId: UserId): DeferredK<Option<PostInfo>> = 
  session.writeTransactionAsync {
    it.runAsync(query, parameters("postId", postId, "userId", userId, "timestamp", System.currentTimeMillis()))
      .thenCompose(StatementResultCursor::peekAsync)
      .thenApply { record ->
        Option.fromNullable(record).map { 
            PostInfo(
              PostId(it["post"]["id"].asString()), 
              PosterId(it["poster"]["id"].asString()),
              UnknownLikes
            )
        }
      }
  }.k()

fun fetchLikesCount(postId : PostId): DeferredK<Option<LikeStatus>> =
  session.readTransactionAsync { tx ->
    tx.runAsync(notificationQuery, parameters("postId", it.a))
      .thenCompose(StatementResultCursor::peekAsync)
      .thenApply { record ->
        Option.fromNullable(record).map { it["likesCount"].asInt() }
      }
  }.k()


fun fetchAllPostInfo(query: Query, postId: PostId, userId: UserId): DeferredK<Option<PostInfo>>
  OptionT.monad(DeferredK.monad()).binding {
    val persistedPost = OptionT(fetchPostIds(query, postId, userId)).bind()
    val likesCount = OptionT(fetchLikesCount(persistedPost.Id)).bind() //do you really need the post id from the persisted one or can we fetch in parallel?
  }.fix().value()
More info http://arrow-kt.io/docs/datatypes/optiont/
a
Hey, thanks for the detailed example. I will check more into transformers. Yes I do need the post id and we can't fetch in parallel.
It is not really
Deferred<Option>
though. It is a
CompletionStage<Option>
,