Skip to content

Instantly share code, notes, and snippets.

View deeperunderstanding's full-sized avatar
Tinkering

A Deeper Understanding deeperunderstanding

Tinkering
View GitHub Profile
fun main() {
val lines = Try {
File("./my-pets.csv").readLines().map { it.split(',') }
}
val pets : Try<ResultSet<Pet>> = lines.map {
it.map(::toPet).asResultSet().map { pet -> pet.copy(name = pet.name.toUpperCase()) }
}
typealias ResultSet<T> = Pair<List<Success<T>>, List<Failure<T>>>
fun <T> List<Try<T>>.asResultSet(): ResultSet<T> = this.partition { it is Success } as ResultSet<T>
fun <T, R> ResultSet<T>.map(transform: (T) -> R): ResultSet<R> =
this.first.map { it.map(transform) }.asResultSet().let { result ->
Pair(result.first, this.second as List<Failure<R>> + result.second)
}
fun main() {
val resultA : Try<String> = Try { "Hello, World" }
val resultB : Try<String> = Try { throw Exception("Not Today!") }
println(resultA)
println(resultB)
}
fun toPet(values: List<String>): Try<Pet> {
val name = values[0]
val ageTry = Try { values[1].toInt() }.recoverWith { Failure<Int>(Exception("Cannot extract age!")) }
val typeTry = PetType.lookup(values[2]).recover { PetType.Invalid }
return ageTry.flatMap { age -> typeTry.map { type -> Pet(name, age, type) } }
}
enum class PetType(val type: String) {
fun toPet(values: List<String>): Try<Pet> {
val name = values[0]
val ageTry = Try { values[1].toInt() }
val typeTry = PetType.lookup(values[2])
return ageTry.flatMap { age -> typeTry.map { type -> Pet(name, age, type) } }
}
enum class PetType(val type: String) {
sealed class Try<T> {
companion object {
operator fun <T> invoke(func: () -> T): Try<T> =
try {
Success(func())
} catch (error: Exception) {
Failure(error)
}
}
object TrySequence {
operator fun <T> Try<T>.component1(): T = when (this) {
is Success -> this.value
is Failure -> throw this.error
}
}
fun <T> Try.Companion.sequential(func: TrySequence.() -> T): Try<T> {
return Try { func(TrySequence) }
}
fun toPet(values: List<String>) = Try.sequential {
val name = values[0]
val (age) = Try { values[1].trim().toInt() }
val (type) = PetType.lookup(values[2].trim())
Pet(name, age, type)
}
fun main() {
val lines = Try {
File("./my-pets.csv").readLines().map { it.split(',') }
}
val pets : Try<List<Pet>> = lines.flatMap { Try.traverse(it, ::toPet) }
when (pets) {
is Success -> println(pets.value)
fun <T, R> Try.Companion.traverse(list: List<T>, transform: (T) -> Try<R>): Try<List<R>> = Try {
val newList = mutableListOf<R>()
for (value in list) {
when(val result = transform(value)) {
is Success -> newList.add(result.value)
is Failure -> throw result.error
}
}
newList
}