CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-arrow-kt--arrow-core-iosx64

Functional companion to Kotlin's Standard Library providing type-safe error handling and functional programming constructs for iOS x64 target

Pending
Overview
Eval results
Files

utility-functions.mddocs/

Utility Functions

Arrow Core provides various utility functions, extensions, and type aliases that enhance Kotlin's standard library with functional programming patterns.

Core Utility Functions

// Identity function - returns input unchanged
fun <A> identity(a: A): A

// Constant function - returns constant value regardless of input
fun <P1, T> constant(t: T): (P1) -> T

String Extensions

// Escape special characters in strings
fun String.escaped(): String  // Escapes \n, \r, \", \', \t, \b

Result Extensions

// FlatMap for Result type
fun <A, B> Result<A>.flatMap(transform: (value: A) -> Result<B>): Result<B>

Type Aliases

// Functional type aliases
typealias Predicate<T> = (T) -> Boolean
typealias Nel<A> = NonEmptyList<A>
typealias EitherNel<E, A> = Either<NonEmptyList<E>, A>
typealias IorNel<A, B> = Ior<Nel<A>, B>

Predicate Extensions

// Map predicate to work with nullable values
fun <T : Any> Predicate<T>.mapNullable(): (T?) -> Boolean

Internal Optimization Utilities

// Internal optimization object for performance
object EmptyValue {
    fun <A> unbox(value: Any?): A
    fun <T> combine(first: Any?, second: T, combine: (T, T) -> T): T
    fun <T, R> fold(value: Any?, ifEmpty: () -> R, ifNotEmpty: (T) -> R): R
}

Tuple Building Operations

// Build larger tuples from smaller ones
operator fun <A, B, C> Pair<A, B>.plus(c: C): Triple<A, B, C>
operator fun <A, B, C, D> Triple<A, B, C>.plus(d: D): Tuple4<A, B, C, D>
operator fun <A, B, C, D, E> Tuple4<A, B, C, D>.plus(e: E): Tuple5<A, B, C, D, E>
operator fun <A, B, C, D, E, F> Tuple5<A, B, C, D, E>.plus(f: F): Tuple6<A, B, C, D, E, F>
operator fun <A, B, C, D, E, F, G> Tuple6<A, B, C, D, E, F>.plus(g: G): Tuple7<A, B, C, D, E, F, G>
operator fun <A, B, C, D, E, F, G, H> Tuple7<A, B, C, D, E, F, G>.plus(h: H): Tuple8<A, B, C, D, E, F, G, H>
operator fun <A, B, C, D, E, F, G, H, I> Tuple8<A, B, C, D, E, F, G, H>.plus(i: I): Tuple9<A, B, C, D, E, F, G, H, I>

Comparison Extensions

// Lexicographic comparison for Pair and Triple
operator fun <A : Comparable<A>, B : Comparable<B>> Pair<A, B>.compareTo(other: Pair<A, B>): Int
operator fun <A : Comparable<A>, B : Comparable<B>, C : Comparable<C>> Triple<A, B, C>.compareTo(other: Triple<A, B, C>): Int

// Iterable comparison
operator fun <A : Comparable<A>> Iterable<A>.compareTo(other: Iterable<A>): Int

Usage Examples

Identity and Constant Functions

import arrow.core.*

// Identity function - useful in higher-order functions
val numbers = listOf(1, 2, 3, 4, 5)
val unchanged = numbers.map(::identity)  // [1, 2, 3, 4, 5]

// Constant function - always returns the same value
val alwaysTrue = constant<String, Boolean>(true)
val results = listOf("hello", "world").map(alwaysTrue)  // [true, true]

// Useful in conditional operations
val defaultValue = constant<Any?, String>("default")
val values = listOf(null, "actual").map { it ?: defaultValue(it) }  // ["default", "actual"]

String Escaping

import arrow.core.*

// Escape special characters
val rawString = "Hello\nWorld\t\"quoted\""
val escaped = rawString.escaped()
// Result: "Hello\\nWorld\\t\\\"quoted\\\""

// Useful for logging or JSON output
val logMessage = "User input: ${userInput.escaped()}"
val jsonValue = "\"${rawValue.escaped()}\""

Result FlatMap

import arrow.core.*

// Chain Result operations
fun parseNumber(input: String): Result<Int> = runCatching { input.toInt() }
fun validatePositive(number: Int): Result<Int> = 
    if (number > 0) Result.success(number) else Result.failure(IllegalArgumentException("Must be positive"))

fun processInput(input: String): Result<Int> =
    parseNumber(input).flatMap { number ->
        validatePositive(number)
    }

val valid = processInput("42")    // Success(42)
val invalid = processInput("-5")  // Failure(IllegalArgumentException)
val error = processInput("abc")   // Failure(NumberFormatException)

Tuple Building

import arrow.core.*

// Build tuples incrementally
val name = "Alice" to "Smith"                    // Pair<String, String>
val withAge = name + 25                          // Triple<String, String, Int>
val withCity = withAge + "NYC"                   // Tuple4<String, String, Int, String>
val withJob = withCity + "Engineer"              // Tuple5<String, String, Int, String, String>

// Chain operations
val coordinates = 10 to 20
val point3D = coordinates + 30
val withLabel = point3D + "origin"
val withTimestamp = withLabel + System.currentTimeMillis()
// Result: Tuple5<Int, Int, Int, String, Long>

// Useful for building complex data structures
fun buildUserProfile(name: String, age: Int): Tuple9<String, Int, String, String, Boolean, Long, String, String, String> {
    return name to age + 
           "Unknown City" + 
           "Unknown Job" + 
           true + 
           System.currentTimeMillis() + 
           "Active" + 
           "Standard" + 
           "No notes"
}

Predicate Operations

import arrow.core.*

// Work with predicates
val isEven: Predicate<Int> = { it % 2 == 0 }
val isPositive: Predicate<Int> = { it > 0 }

val numbers = listOf(1, 2, 3, 4, 5, 6)
val evenNumbers = numbers.filter(isEven)      // [2, 4, 6]
val positiveNumbers = numbers.filter(isPositive)  // [1, 2, 3, 4, 5, 6]

// Map to work with nullable values
val nullableIsEven = isEven.mapNullable()
val nullableNumbers = listOf(1, null, 2, null, 3)
val results = nullableNumbers.map(nullableIsEven)  // [false, false, true, false, false]

Type Aliases Usage

import arrow.core.*

// Use convenient type aliases
fun validateUsers(users: List<String>): EitherNel<String, List<String>> {
    val errors = mutableListOf<String>()
    val validUsers = users.filter { user ->
        when {
            user.isBlank() -> {
                errors.add("Empty user name")
                false
            }
            user.length < 2 -> {
                errors.add("User name too short: $user")
                false
            }
            else -> true
        }
    }
    
    return if (errors.isEmpty()) {
        validUsers.right()
    } else {
        errors.toNonEmptyListOrNull()!!.left()
    }
}

// Use Nel alias for conciseness
fun processItems(items: Nel<String>): String {
    return "Processing ${items.size} items starting with '${items.head}'"
}

// Use IorNel for partial results with warnings
fun validateWithWarnings(input: String): IorNel<String, String> {
    val warnings = mutableListOf<String>()
    
    if (input.startsWith(" ") || input.endsWith(" ")) {
        warnings.add("Input has leading or trailing whitespace")
    }
    
    val cleaned = input.trim()
    
    return if (cleaned.isEmpty()) {
        listOf("Input is empty after trimming").toNonEmptyListOrNull()!!.leftIor()
    } else if (warnings.isNotEmpty()) {
        Ior.Both(warnings.toNonEmptyListOrNull()!!, cleaned)
    } else {
        cleaned.rightIor()
    }
}

Comparison Operations

import arrow.core.*

// Compare pairs lexicographically
val pairs = listOf(
    "apple" to 10,
    "banana" to 5, 
    "apple" to 15,
    "cherry" to 3
)

val sorted = pairs.sorted()
// Result: [("apple", 10), ("apple", 15), ("banana", 5), ("cherry", 3)]

// Compare triples
val coordinates = listOf(
    Triple(1, 2, 3),
    Triple(1, 1, 4),
    Triple(2, 1, 1),
    Triple(1, 2, 2)
)

val sortedCoords = coordinates.sorted()
// Result: [(1, 1, 4), (1, 2, 2), (1, 2, 3), (2, 1, 1)]

// Compare iterables
val lists = listOf(
    listOf(1, 2, 3),
    listOf(1, 2),
    listOf(1, 3),
    listOf(1, 2, 4)
)

val sortedLists = lists.sorted()
// Result: [[1, 2], [1, 2, 3], [1, 2, 4], [1, 3]]

Install with Tessl CLI

npx tessl i tessl/maven-io-arrow-kt--arrow-core-iosx64

docs

collection-extensions.md

error-handling.md

index.md

optional-values.md

partial-results.md

product-types.md

raise-dsl.md

safe-collections.md

utility-functions.md

tile.json