forked from nulang-org/nulang
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path14_option_result.nula
More file actions
130 lines (103 loc) · 4.08 KB
/
Copy path14_option_result.nula
File metadata and controls
130 lines (103 loc) · 4.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// 14_option_result.nula - Option and Result combinators
// Demonstrates: Option and Result types, map, unwrap, pattern matching,
// is_some, is_ok, catch expressions
//
// Run: nulang examples/14_option_result.nula
// ── Types (defined inline, matching stdlib) ──────────────────────────────
type Option[T] = Some(T) | None
type Result[T, E] = Ok(T) | Error(E)
// ── Option combinators ───────────────────────────────────────────────────
let is_some = fn(opt) {
match opt {
| Some(_) => true
| None => false
}
}
let is_none = fn(opt) {
match opt {
| Some(_) => false
| None => true
}
}
let unwrap = fn(opt, default) {
match opt {
| Some(x) => x
| None => default
}
}
let map_option = fn(opt, f) {
match opt {
| Some(x) => Some(f(x))
| None => None
}
}
// ── Result combinators ───────────────────────────────────────────────────
let is_ok = fn(r) {
match r {
| Ok(_) => true
| Error(_) => false
}
}
let is_err = fn(r) {
match r {
| Ok(_) => false
| Error(_) => true
}
}
let unwrap_result = fn(r, default) {
match r {
| Ok(x) => x
| Error(_) => default
}
}
// ── Demo ─────────────────────────────────────────────────────────────────
perform IO.print("=== Option ===")
let some_val = Some(42)
let none_val = None
perform IO.print("is_some Some(42): " + perform Int.to_string(if is_some(some_val) then 1 else 0))
perform IO.print("is_some None: " + perform Int.to_string(if is_some(none_val) then 1 else 0))
perform IO.print("is_none None: " + perform Int.to_string(if is_none(none_val) then 1 else 0))
// map over Option
let doubled = map_option(some_val, fn(x) { x * 2 })
perform IO.print("map Some(42) *2: " + perform Int.to_string(unwrap(doubled, -1)))
let mapped_none = map_option(none_val, fn(x) { x * 2 })
perform IO.print("map None *2: " + perform Int.to_string(if is_none(mapped_none) then 1 else 0))
// unwrap
perform IO.print("unwrap Some(99): " + perform Int.to_string(unwrap(Some(99), -1)))
// Pattern match on Option
let describe = fn(opt) {
match opt {
| Some(x) => "Some(" + perform Int.to_string(x) + ")"
| None => "None"
}
}
perform IO.print(describe(Some(7)))
perform IO.print(describe(None))
// ── Result ──────────────────────────────────────────────────────────────
perform IO.print("=== Result ===")
let ok_val = Ok(100)
let err_val = Error("something went wrong")
perform IO.print("is_ok Ok(100): " + perform Int.to_string(if is_ok(ok_val) then 1 else 0))
perform IO.print("is_ok Error(_): " + perform Int.to_string(if is_ok(err_val) then 1 else 0))
perform IO.print("is_err Error(_):" + perform Int.to_string(if is_err(err_val) then 1 else 0))
// unwrap
perform IO.print("unwrap Ok(42): " + perform Int.to_string(unwrap_result(Ok(42), -1)))
// Pattern match on Result
let result_desc = fn(r) {
match r {
| Ok(x) => "Ok(" + perform Int.to_string(x) + ")"
| Error(e) => "Error(" + e + ")"
}
}
perform IO.print(result_desc(Ok(200)))
perform IO.print(result_desc(Error("not found")))
// Safe division with Result + catch
let safe_div = fn(a, b) {
if b == 0 then Error("div by zero") else Ok(a / b)
}
// Catch unwraps Ok, so the result is the inner value (or the fallback on Error).
let r1 = safe_div(10, 2) catch -1
perform IO.print("safe_div(10, 2) catch -1 = " + perform Int.to_string(r1))
let r2 = safe_div(10, 0) catch -1
perform IO.print("safe_div(10, 0) catch -1 = " + perform Int.to_string(r2))
perform IO.print("Option/Result demo complete!")