๐Ÿฆ€ Functional Rust
๐ŸŽฌ Error Handling in Rust Option, Result, the ? operator, and combinators.
๐Ÿ“ Text version (for readers / accessibility)

โ€ข Option represents a value that may or may not exist โ€” Some(value) or None

โ€ข Result represents success (Ok) or failure (Err) โ€” no exceptions needed

โ€ข The ? operator propagates errors up the call stack concisely

โ€ข Combinators like .map(), .and_then(), .unwrap_or() chain fallible operations

โ€ข The compiler forces you to handle every error case โ€” no silent failures

309: The Never Type (!)

Difficulty: 4 Level: Expert `!` is the bottom type โ€” a computation that never produces a value โ€” and it fits anywhere in the type system.

The Problem This Solves

Every expression in Rust has a type. But some expressions never finish: they panic, loop forever, or call `std::process::exit()`. What type should those have? If `panic!()` had type `()`, it couldn't appear in match arms that expect `i32`. If it had type `i32`, it couldn't appear where a `String` is needed. The answer is `!` โ€” the never type, the bottom of the type lattice. A value of type `!` can never exist, which means it can pretend to be any type. This isn't a hack; it's mathematically sound. From a false premise, you can prove anything (ex falso quodlibet). If `!` had a value, you could use it as an `i32`, a `String`, or anything else โ€” but since it never does, the coercion is always vacuously safe. This matters practically in error handling: `Infallible` (a zero-variant enum, equivalent to `!`) is the error type for conversions that literally cannot fail, and `Result<T, !>` can only ever be `Ok(T)`.

The Intuition

Think of `!` as a mathematical guarantee: "this code path is unreachable." When you write a function returning `!`, you're promising the compiler that the function never returns normally. The compiler trusts this and allows `!` expressions to unify with any other type โ€” like a wildcard in pattern matching. `Infallible` is `!` made stable and nameable. It's an enum with zero variants โ€” you cannot construct a value of it, ever. So `Result<T, Infallible>` is effectively `T` wrapped in a `Result`, and you can `.unwrap()` it knowing it will never panic.

How It Works in Rust

// Functions returning ! never return normally
fn crash(msg: &str) -> ! {
 panic!("{}", msg)
}

// ! coerces to any type โ€” valid in match arms
fn parse_or_die(s: &str) -> i32 {
 s.parse().unwrap_or_else(|_| crash("parse failed"))
 //                              ^^^^^^^^^^^^^^^^^ : ! coerces to i32
}

// Infallible: can never be constructed
use std::convert::Infallible;
let r: Result<i32, Infallible> = Ok(42);
let val = r.unwrap(); // safe โ€” Err variant is impossible

// Result<T, Infallible> can match with only the Ok arm
let val = match r {
 Ok(v) => v,
 // Err arm omitted โ€” compiler knows Infallible has no values
};

// From<!> for T is implemented for all T
// From<Infallible> for T is implemented via the same logic

What This Unlocks

Key Differences

ConceptOCamlRust
Never type`'a` (universal polymorphism)`!` (explicit bottom type)
Diverging coercionImplicit (any diverging expr)`!` coerces to any type
Infallible errorPhantom type / `exn` workaround`std::convert::Infallible`
Match on empty typeImpossible pattern`match inf {}` (zero arms)
Process exit`exit` returns `unit``std::process::exit() -> !`
//! 309. The ! (never) type in error handling
//!
//! `!` is the never/bottom type: diverging functions, `Infallible`, exhaustive matches.

use std::convert::Infallible;

/// A function that never returns โ€” return type `!`
fn crash(msg: &str) -> ! {
    panic!("{}", msg)
}

/// `!` coerces to any type โ€” useful in match arms
fn parse_or_crash(s: &str) -> i32 {
    s.parse::<i32>().unwrap_or_else(|e| crash(&format!("fatal parse error: {}", e)))
}

/// Result<T, Infallible> can only be Ok โ€” infallible conversion
fn to_uppercase(s: &str) -> Result<String, Infallible> {
    Ok(s.to_uppercase())
}

/// From<Infallible> coercion: convert Result<T, Infallible> to T
fn infallible_result() {
    let r: Result<i32, Infallible> = Ok(42);
    // Since Infallible has no values, we can exhaustively match with only Ok arm
    let val = match r {
        Ok(v) => v,
        // Err(e) => match e {} // would need this, but Infallible has no variants
    };
    println!("Infallible result: {}", val);
    // Or use unwrap โ€” can never panic since Err is impossible
    let val2: i32 = Ok::<i32, Infallible>(99).unwrap();
    println!("unwrap on Infallible: {}", val2);
}

/// The never type in match arms (! coerces to anything)
fn process(s: &str) -> i32 {
    if let Ok(n) = s.parse::<i32>() {
        n
    } else {
        crash("this input is always a number") // -> ! coerces to i32
    }
}

fn main() {
    println!("parse_or_crash('42') = {}", parse_or_crash("42"));

    let upper: Result<String, Infallible> = to_uppercase("hello");
    println!("Infallible: {:?}", upper);

    // Convert Infallible result to value (always safe)
    let val: String = upper.unwrap_infallible();
    println!("Unwrapped: {}", val);

    infallible_result();

    // Never type in closures
    let _f: fn() -> ! = || panic!("never");
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::convert::Infallible;

    #[test]
    fn test_infallible_is_ok() {
        let r: Result<i32, Infallible> = Ok(42);
        assert!(r.is_ok());
        assert_eq!(r.unwrap(), 42);
    }

    #[test]
    fn test_to_uppercase_infallible() {
        let r = to_uppercase("rust");
        assert_eq!(r.unwrap(), "RUST");
    }

    #[test]
    fn test_parse_or_crash() {
        assert_eq!(parse_or_crash("100"), 100);
    }

    #[test]
    #[should_panic]
    fn test_crash_panics() {
        crash("intentional crash");
    }
}

// Extension trait for unwrap_infallible
trait UnwrapInfallible<T> {
    fn unwrap_infallible(self) -> T;
}

impl<T> UnwrapInfallible<T> for Result<T, Infallible> {
    fn unwrap_infallible(self) -> T {
        match self {
            Ok(v) => v,
        }
    }
}
(* 309. The never type in error handling - OCaml *)
(* OCaml: diverging functions have type 'a (polymorphic) *)

(* A function that never returns (loops) *)
let rec loop () : 'a = loop ()

(* A function that always panics *)
let abort msg : 'a = failwith msg

(* Simulating Infallible with an uninhabited type *)
type infallible = |  (* empty variant -- OCaml 4.11+ *)

let to_result : int -> (int, infallible) result = fun n -> Ok n

let () =
  let r = to_result 42 in
  (* exhaustive match: Err case is impossible *)
  let v = match r with
    | Ok n -> n
    | Error _ -> assert false  (* dead code *)
  in
  Printf.printf "Value: %d\n" v;

  (* Using option to simulate ? with never-returning branches *)
  let find_first pred lst =
    match List.find_opt pred lst with
    | Some v -> v
    | None -> failwith "precondition violated: element must exist"
  in
  let v = find_first (fun x -> x > 3) [1; 2; 3; 4; 5] in
  Printf.printf "First > 3: %d\n" v