julian
10/12/2020, 6:02 PMjulian
10/12/2020, 6:03 PMjulian
10/12/2020, 6:07 PMjulian
10/12/2020, 7:57 PMKirill
10/14/2020, 7:40 PMjulian
10/26/2020, 5:44 PMtim
11/06/2020, 6:53 PMjulian
11/08/2020, 7:20 PMpajatopmr
03/28/2021, 5:51 AMpajatopmr
03/28/2021, 12:51 PMz
and f
.julian
03/28/2021, 7:51 PMjulian
03/28/2021, 8:11 PMpajatopmr
04/19/2021, 9:23 PMGiovan
09/10/2021, 2:04 PMsealed class
) and pattern matching (when
) to enable functions to match different types to complete different tasks.
This makes most of my functions need to do a pattern matching on the type, which makes me feel a little clumsy, and if I need to add a new type, I need to add a case to each of these functions, it is easy to miss the new case.
The following is a fictitious code example, assuming it is a sticky note model.
sealed class Resource {
data class Note(val content: String?) : Resource()
data class Tag(val name: String?) : Resource()
data class Character(val name: String?) : Resource()
data class Address(val latitude: Float?, val longitude: Float?) : Resource()
}
fun pullResource(): List<Resource> = TODO()
fun Resource.toDecrypt(): Resource = when (this) {
is Resource.Note -> TODO()
is Resource.Tag -> TODO()
is Resource.Character -> TODO()
is Resource.Address -> TODO()
}
fun Resource.checkLegal(): Boolean = when (this) {
is Resource.Note -> content != null
is Resource.Tag -> name != null
is Resource.Character -> name != null
is Resource.Address -> latitude != null && longitude != null
}
inline fun <reified T> List<T>.insert() {
when (T::class) {
Resource.Note::class -> TODO("batch insert into the Note Entity")
Resource.Tag::class -> TODO("batch insert into the Tag Entity")
Resource.Character::class -> TODO("batch insert into the Character Entity")
Resource.Address::class -> TODO("batch insert into the Address Entity")
}
}
fun insertDB(l: List<Resource>) {
fun <T : Resource> List<Resource>.cast(): List<T> = this as List<T>
l.groupBy {
when (it) {
is Resource.Note -> "Note"
is Resource.Tag -> "Tag"
is Resource.Character -> "Character"
is Resource.Address -> "Address"
}
}.let {
it["Note"]?.cast<Resource.Note>()?.insert()
it["Tag"]?.cast<Resource.Tag>()?.insert()
it["Character"]?.cast<Resource.Character>()?.insert()
it["Address"]?.cast<Resource.Address>()?.insert()
}
}
fun main() {
pullResource().map(Resource::toDecrypt).filter(Resource::checkLegal).let(::insertDB)
}
I donāt know if this is right, it feel weird to me.
If in OO style, I thought maybe i can define an interface for Resource, and implement the interface when adding cases. The code is clean and does not miss new cases.Randall Perry
09/22/2021, 5:56 PMRandall Perry
09/22/2021, 6:02 PMfun <A> sequence(fs: FList<Rand<A>>): Rand<FList<A>> = { rng ->
when (fs) {
is FList.Nil -> unit(FList.empty<A>())(rng)
is FList.Cons -> {
val (a, nrng) = fs.head(rng)
val (xa, frng) = sequence(fs.tail)(nrng)
FList.Cons(a, xa) to frng
}
}
}
This 1st answer was said to be not stack-safe, and the correct solution uses foldRight.
But, Iām trying to understand the syntax. They have the ārngā or the ānrngā var enclosed in parantheses following the two return values:
unit(FList.empty<A>())(rng)
sequence(fs.tail)(nrng)
What does this mean? Is invoke being called via the parantheses? Or is the RNG type getting passed thru?dnowak
11/29/2021, 12:35 AMRace
02/27/2022, 2:02 AMType inference failed. The value of the type parameter T should be mentioned in input types (argument types, receiver type or expected type). Try to specify it explicitly.
Race
02/27/2022, 2:03 AMAlexandre A Barbosa
01/20/2023, 6:48 PMAlexandre A Barbosa
06/01/2023, 8:20 PMwhen(notificationType) {
"x" -> npRepository.findByIdOrNull(notificationId)?.let {
npsRepository.findByXId(notificationId, userId)
.takeIf { it.isNotEmpty() }
?.map { it.apply { isRead = notificationRead } }
?.let { npsRepository.saveAll(it) }
?: npsRepository.save(
NPS(
notificationPlatformId = notificationId,
userId = userId,
isRead = notificationRead
)
)
} ?: logAndThrowNotFound(notificationType, notificationId, throwNotFound)
"y" ->
ntRepository.findByIdOrNull(notificationId)?.let {
ntsRepository.findByXId(notificationId, userId)
.takeIf { it.isNotEmpty() }
?.map { it.apply { isRead = notificationRead } }
?.let { ntsRepository.saveAll(it)}
?: ntsRepository.save(NTS(
notificationTenantId = notificationId,
userId = userId,
isRead = notificationRead
)
)
} ?: logAndThrowNotFound(notificationType, notificationId, throwNotFound)
...
}