union IntResult {
    Ok { value: Int }
    Err { error: String }
}

: is-ok? ( IntResult -- Bool )
    match
        Ok { >value } -> drop true
        Err { >error } -> drop false
    end
;

: is-err? ( IntResult -- Bool )
    match
        Ok { >value } -> drop false
        Err { >error } -> drop true
    end
;

: safe-divide ( Int Int -- IntResult )
    dup 0 i.= [
        drop drop
        "division by zero" Make-Err
    ] [
        i./ drop    # drop the success Bool, we already checked for zero
        Make-Ok
    ] if
;

: test-safe-divide-ok ( -- )
    10 2 safe-divide is-ok?
    test.assert
;

: test-safe-divide-err ( -- )
    10 0 safe-divide is-err?
    test.assert
;

: test-safe-divide-value ( -- )
    10 2 safe-divide
    match
        Ok { >value } ->
        Err { >error } -> drop 0
    end
    5 test.assert-eq
;
