Returning Optionals

Objective: Define fucntions that use Optional to signal successful/unsuccessful operation. Chain them to see how information value is propagated.

Python

from typing import Optional

def div(a: float, b: float) -> Optional[float]:
    if b == 0.0: return None
    return a / b

def div_and_add(a: float, b: float) -> Optional[float]:
    n = div(a, b)
    if n is None: return None

    m = div(b, a)
    if m is None: return None

    s = m + n
    if s >= 10: return None

    return s

print(div_and_add(2.0, 4.0))   # 2.5
print(div_and_add(0.0, 4.0))   # None
print(div_and_add(2.0, 0.0))   # None
print(div_and_add(100.0, 1.0)) # None

Rust

fn div(a: f32, b: f32) -> Option<f32> {
    if b == 0.0 {
        None
    } else {
        Some(a / b)
    }
}

fn div_and_add(a: f32, b: f32) -> Option<f32> {
    let n = div(a, b)?;
    let m = div(b, a)?;
    let s = m + n;

    if s >= 10.0 {
        None
    } else {
        Some(s)
    }
}

fn show(a: f32, b: f32) {
    println!("{:?}", div_and_add(a, b));
}

fn main() {
    show(2.0, 4.0);   // 2.5
    show(0.0, 4.0);   // None
    show(2.0, 0.0);   // None
    show(100.0, 1.0); // None
}

Crystal

def div(a : Float32, b : Float32) : Float32?
  return nil if b == 0.0
  a / b
end

def div_and_add(a : Float32, b : Float32) : Float32?
  div(a, b).try do |n|
    div(b, a).try do |m|
      if (s = m + n) < 10
        s
      end
    end
  end
end

def show(a : Float32, b : Float32)
  puts div_and_add(a, b) || "None"
end

show(2.0, 4.0)   # 2.5
show(0.0, 4.0)   # None
show(2.0, 0.0)   # None
show(100.0, 1.0) # None