Kotlin
Beginner
1 min read
Sealed Classes and Algebraic Data Types
Example
// Network result as sealed class hierarchy
sealed class NetworkResult<out T> {
data class Success<T>(val data: T) : NetworkResult<T>()
data class Error(val code: Int, val msg: String) : NetworkResult<Nothing>()
object Loading : NetworkResult<Nothing>()
}
data class Post(val id: Int, val title: String)
fun fetchPost(id: Int): NetworkResult<Post> = when (id) {
0 -> NetworkResult.Loading
else -> if (id > 0)
NetworkResult.Success(Post(id, "Post #$id"))
else
NetworkResult.Error(404, "Not found")
}
// Exhaustive when expression — compiler ensures all cases covered
fun render(result: NetworkResult<Post>): String = when (result) {
is NetworkResult.Loading -> "Loading..."
is NetworkResult.Success -> "Post: ${result.data.title}"
is NetworkResult.Error -> "Error ${result.code}: ${result.msg}"
}
// Sealed interface
sealed interface Expr
data class Num(val value: Double) : Expr
data class Add(val l: Expr, val r: Expr) : Expr
data class Mul(val l: Expr, val r: Expr) : Expr
fun eval(e: Expr): Double = when (e) {
is Num -> e.value
is Add -> eval(e.l) + eval(e.r)
is Mul -> eval(e.l) * eval(e.r)
}
fun main() {
listOf(-1, 0, 5).map(::fetchPost).map(::render).forEach(::println)
val expr = Mul(Add(Num(2.0), Num(3.0)), Num(4.0))
println("Result: ${eval(expr)}") // 20.0
}