Skip to content

Instantly share code, notes, and snippets.

@raulraja
Created May 28, 2021 17:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save raulraja/5ebbd75061343b78260148719e3dcd05 to your computer and use it in GitHub Desktop.
Save raulraja/5ebbd75061343b78260148719e3dcd05 to your computer and use it in GitHub Desktop.
Constraint ADT for Flow Action and Reaction emit
/** 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