Comments 2
Спасибо за качественный пятничный ФП, давненько искал понятный материал по уменьшению бойлерплейта в MVI паттерне (или, как вы тут его назвали MUV)
0
Посидел немного, помучался с особенностями reified generics в Kotlin, понял, что также чисто как на Scala не получится это провернуть (все таки Kotlin не сильно больше FP-friendly, чем Java). Однако есть работающий примерчик, компилятор проверяет все веточки, ругается, где положено, как и заявлено в ТЗ поста. Для этого понадобилось разбить все на отдельные методы под каждый тип состояний (мне кажется, в крупном приложении все равно бы все пришло к этому)
// Иерархия сообщений
sealed class Msg
sealed class MsgLogined : Msg()
object Logout : MsgLogined()
object Greet : MsgLogined()
sealed class MsgLogouted : Msg()
data class Login(val username: String) : MsgLogouted()
// Иерархия модели
sealed class Model<T:Msg>(val messageType: Class<T>)
data class LoggedIn(val username: String) :
Model<MsgLogined>(MsgLogined::class.java)
object Logouted : Model<MsgLogouted>(MsgLogouted::class.java)
// Функции обновления для каждого состояния
fun updateLoggedIn(model:LoggedIn, message: MsgLogined) =
when (message){
is Logout -> Logouted
is Greet -> LoggedIn(model.username)
}
fun updateLogouted(model: Logouted, message: MsgLogouted) =
when (message){
is Login -> LoggedIn(message.username)
}
// Агрегирующая функция обновления
fun <T:Msg> update(model: Model<*>, message: T): Model<*> =
when (model){
is LoggedIn -> updateLoggedIn(model, model.messageType.cast(message))
is Logouted -> updateLogouted(model, model.messageType.cast(message))
}
// Вьюхи
fun printLogin() : MsgLogouted {
println("Login:")
return Login(readLine()!!)
}
fun printGreeting(name: String) : MsgLogined {
println("Hello, $name")
return when (readLine()){
"" -> Logout
else -> Greet
}
}
fun view(model: Model<*>) =
when (model){
is LoggedIn -> printGreeting(model.username)
is Logouted -> printLogin()
}
// Наша аппа
tailrec fun app(model: Model<*>) : Model<*> =
app(update(model, view(model)))
fun main(args: Array<String>) {
app(Logouted)
}
0
Sign up to leave a comment.
Паттерн Model-Update-View и зависимые типы