Created
May 28, 2021 17:30
-
-
Save raulraja/5ebbd75061343b78260148719e3dcd05 to your computer and use it in GitHub Desktop.
Constraint ADT for Flow Action and Reaction emit
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** Dummy login model **/ | |
@JvmInline | |
value class UserName(val value: String) | |
@JvmInline | |
value class Password(val value: String) | |
/** | |
* A [Reaction] is always parametric to a type of [Action] | |
*/ | |
sealed class Reaction<out A : Action> | |
/** | |
* The [LoginReaction] can only be sent for [LoginAction] | |
*/ | |
object LoginReaction : Reaction<LoginAction>() | |
/** | |
* The [Reaction1] can only be sent for [OtherAction] | |
*/ | |
object Reaction1 : Reaction<OtherAction>() | |
/** | |
* The [WhateverReaction] is good for all [Action] | |
*/ | |
object WhateverReaction : Reaction<Nothing>() | |
sealed class Action | |
data class LoginAction(val userName: UserName, val password: Password) : Action() | |
object OtherAction : Action() | |
suspend fun login(userName: UserName, password: Password) { | |
val action = LoginAction(userName, password) | |
val loginFlow = react(action) { LoginReaction } // this is fine because LoginReaction is valid for LoginAction | |
return loginFlow.collect { reaction : LoginReaction -> | |
//here reaction can only be of type LoginReaction | |
} | |
} | |
/** | |
* This is the motherload. This function ensures that a given [Action] [A] | |
* creates a [Flow] of [Reaction] for [R], a Reaction that only accepts actions of type [A] | |
*/ | |
inline fun <A : Action, R : Reaction<A>> react( | |
action: A, | |
crossinline f: (A) -> R | |
): Flow<R> = | |
flow { emit(f(action)) } | |
fun badProgram() { | |
val action: LoginAction = LoginAction(UserName("test"), Password("test")) | |
react(action) { | |
Reaction1 //Type mismatch: inferred type is Reaction1 but Reaction<LoginAction> was expected | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment