#unit

    The unit package provides functionality for working with the singleton type Unit, which represents computations that produce side effects but return no meaningful value. This is a fundamental type in functional programming for operations like I/O, logging, and state modifications.

    #Understanding Unit Type

    The Unit type has exactly one value: (). This might seem trivial, but it serves important purposes in type systems:

    • Side Effect Indication: Functions returning Unit signal they're called for side effects
    • Placeholder Type: Used when a type parameter is needed but no meaningful value exists
    • Functional Programming: Represents "no useful return value" without using null or exceptions
    • Interface Consistency: Maintains uniform function signatures in generic contexts

    #Unit Value Creation

    The unit value can be created in multiple ways:

    ///|
    test "unit construction" {
    // Direct literal syntax
    let u1 = ()

    // Via default constructor
    let u2 = ()
    fn println(_ : String) {

    }
    // All unit values are identical
    @test.assert_eq(u1, u2)

    // Common pattern: functions that return unit
    fn log_message(msg : String) -> Unit {
    // In real code, this would write to a log
    println(msg)
    () // Explicit unit return
    }

    let result = log_message("Hello, world!")
    inspect(result, content="()")
    }

    #Working with Side-Effect Functions

    Functions that return Unit are typically called for their side effects:

    ///|
    test "side effect patterns" {
    let numbers = [1, 2, 3, 4, 5]
    fn println(_ : Int) {

    }
    // Processing for side effects (printing, logging, etc.)
    let processing_result = numbers.fold(init=(), fn(_acc, n) {
    // Simulated side effect
    if n % 2 == 0 {
    // Would print or log in real code
    println(n)
    }
    () // Return unit to continue fold
    })
    inspect(processing_result, content="()")

    // Using each for side effects (more idiomatic)
    numbers.each(fn(n) { if n % 2 == 0 { println(n) } })
    }

    #String Representation and Debugging

    Unit values have a standard string representation for debugging:

    ///|
    test "unit string conversion" {
    let u = ()
    inspect(u.to_string(), content="()")

    // Useful for debugging function results
    fn perform_operation() -> Unit {
    // Some side effect operation
    ()
    }

    let result = perform_operation()
    let debug_msg = "Operation completed: \{result}"
    inspect(debug_msg, content="Operation completed: ()")
    }

    #Generic Programming with Unit

    Unit is particularly useful in generic contexts where you need to represent "no meaningful value":

    ///|
    test "generic unit usage" {
    // Simulating a function that processes data and optionally returns a result
    let items = [1, 2, 3, 4, 5]

    // Process for side effects only
    items.each(x => {
    // Side effect: processing each item
    let processed = x * 2
    assert_true(processed > 0) // Simulated processing validation
    })

    // Unit represents successful completion without meaningful return value
    let completion_status = ()
    inspect(completion_status, content="()")

    // Unit is useful in Result types for operations that succeed but return nothing
    let operation_result : Result[Unit, String] = Ok(())
    debug_inspect(operation_result, content="Ok(())")
    }

    #Built-in Trait Implementations

    Unit implements essential traits for seamless integration with MoonBit's type system:

    ///|
    test "unit trait implementations" {
    let u1 = ()
    let u2 = ()

    // Equality: all unit values are equal
    inspect(u1 == u2, content="true")

    // Comparison: all unit values compare as equal
    inspect(u1.compare(u2), content="0")

    // Hashing: consistent hash values
    let h1 = hash(u1)
    let h2 = hash(u2)
    inspect(h1 == h2, content="true")

    // Default instance
    let u3 = ()
    inspect(u3 == u1, content="true")
    }

    #Practical Use Cases

    #Result Accumulation

    ///|
    test "result accumulation" {
    // Accumulating side effects without meaningful return values
    let operations = [
    fn() { () }, // Operation 1
    fn() { () }, // Operation 2
    fn() { () },
    ] // Operation 3
    let final_result = operations.fold(init=(), fn(acc, operation) {
    operation() // Execute the operation
    acc // Accumulate unit values
    })
    inspect(final_result, content="()")
    }

    #Builder Pattern Termination

    ///|
    test "builder pattern" {
    // Simulating a builder pattern where build() returns Unit
    let settings = ["debug=true", "timeout=30"]

    // Build operation returns Unit after applying configuration
    fn apply_config(config_list : Array[String]) -> Unit {
    // In real code: apply configuration settings
    let _has_settings = config_list.length() > 0
    () // Unit indicates successful completion
    }

    let result = apply_config(settings)
    inspect(result, content="()")
    }

    The Unit type provides essential functionality for representing "no meaningful return value" in a type-safe way, enabling clean functional programming patterns and consistent interfaces across MoonBit code.

    default

    #deprecated("Use `Unit::default` instead")
    fn default() -> Unit

    same as Unit::default

    Source Files