Result
The Result module provides utilities for error handling. Result types represent operations that can succeed with a value or fail with an error, providing a type-safe alternative to exceptions.
Constructors
Results are created using the Ok and Err constructors,
which are pre-registered in Kit and available without import.
Constructors
Ok
a -> Result a e
Wraps a value in an Ok, indicating the operation succeeded.
value = Ok 42
name = Ok "Alice"
Err
e -> Result a e
Wraps an error value in an Err, indicating the operation failed.
error = Err "File not found"
invalid = Err { code: 404, message: "Not found" }
Predicates
Result.is-ok?
Result a e -> Bool
Returns
true if the result is an Ok value.
println (Result.is-ok? (Ok 42))
# => true
println (Result.is-ok? (Err "error"))
# => false
Result.is-err?
Result a e -> Bool
Returns
true if the result is an Err value.
println (Result.is-err? (Err "error"))
# => true
println (Result.is-err? (Ok 42))
# => false
is-ok?
Result a e -> Bool
Bare function that checks if a result is an Ok value.
println (is-ok? (Ok 42))
# => true
is-err?
Result a e -> Bool
Bare function that checks if a result is an Err value.
println (is-err? (Err "error"))
# => true
Transforming
Result.map
(a -> b) -> Result a e -> Result b e
Applies a function to the value inside an Ok, or passes through the Err.
double = fn(x) => x * 2
result = Result.map double (Ok 21)
# => Ok 42
error = Result.map double (Err "failed")
# => Err "failed"
Result.map-err
(e -> f) -> Result a e -> Result a f
Applies a function to the error inside an Err, or passes through the Ok.
add-context = fn(err) => "Database error: ${err}"
result = Result.map-err add-context (Err "connection refused")
# => Err "Database error: connection refused"
Unwrapping
Result.unwrap
Result a e -> a
Returns the value inside an Ok. Raises an error if Err.
Prefer
Result.unwrap-or or pattern matching when possible.
value = Result.unwrap (Ok 42)
# => 42
# This will raise an error:
# Result.unwrap (Err "failed")
Result.unwrap-or
a -> Result a e -> a
Returns the value inside an Ok, or the provided default if Err.
value = Result.unwrap-or 0 (Ok 42)
# => 42
default = Result.unwrap-or 0 (Err "error")
# => 0
Chaining
Result.and-then
(a -> Result b e) -> Result a e -> Result b e
Chains fallible operations. If the input is Ok, applies the function.
If Err, passes through the error.
parse-int = fn(s) =>
match String.to-int s
| Some n -> Ok n
| None -> Err "Invalid integer"
validate-positive = fn(n) =>
if n > 0 then Ok n else Err "Must be positive"
result = Ok "42"
|> Result.and-then parse-int
|> Result.and-then validate-positive
# => Ok 42
Pattern Matching with Results
Results are typically handled using pattern matching:
process = fn(result) =>
match result
| Ok value -> "Success: ${value}"
| Err error -> "Error: ${error}"
println (process (Ok 42))
# => "Success: 42"
println (process (Err "not found"))
# => "Error: not found"
Common Patterns
Combining Multiple Results
read-config = fn(path) =>
match File.read path
| Ok content -> Ok content
| Err err -> Err "Config error: ${err}"
validate-config = fn(content) =>
if String.length content > 0
then Ok content
else Err "Config is empty"
# Chain operations using pipe and and-then
config = read-config "app.toml"
|> Result.and-then validate-config
|> Result.map String.trim
Converting Option to Result
ok-or = fn(error, option) =>
match option
| Some value -> Ok value
| None -> Err error
result = Map.get "key" my-map |> ok-or "Key not found"