signalis-eb/godot/addons/monads/option.gd

136 lines
2.7 KiB
GDScript

class_name Option extends RefCounted
static var Unit = Option.some(null)
static func some(value: Variant) -> Option:
return Some.new(value)
static var none: Option.None = None.new()
static func from(value: Variant) -> Option:
if typeof(value) == TYPE_NIL:
return Option.none
else: return Option.some(value)
static func collect_some(options: Array[Option], ignore_none: bool = false) -> Option:
var result = []
for option in options:
if option.is_some():
result.push_back(option.unwrap())
elif not ignore_none:
return Option.none
return Option.some(result)
class Some extends Option:
var value: Variant
func _init(val: Variant) -> void:
value = val
func and_then(fn: Callable) -> Option:
return fn.call(value)
func and_other(other: Option) -> Option:
return other
func contains(target_value: Variant) -> bool:
return value == target_value
func filter(fn: Callable) -> Option:
if fn.call(value): return self
else: return Option.none
func flatten() -> Option:
if value is Option:
return value.flatten()
else: return Option.some(value)
func map(fn: Callable) -> Option:
return Option.some(fn.call(value))
func ok_or(_err: Variant) -> Result:
return Result.ok(value)
func ok_or_else(fn: Callable) -> Result:
return Result.ok(value)
func or_other(option: Option) -> Option:
return self
func inspect(fn: Callable) -> Option:
fn.call(value)
return self
func is_some() -> bool:
return true
func is_none() -> bool:
return false
func unwrap() -> Variant:
return value
func unwrap_or(_default_value: Variant) -> Variant:
return value
func unwrap_or_else(_fn: Callable) -> Variant:
return value
func xor_other(other: Option) -> Option:
if other.is_none():
return self
else:
return Option.none
class None extends Option:
func and_then(_fn: Callable) -> Option:
return self
func and_other(other: Option) -> Option:
return self
func contains(value: Variant) -> bool:
return false
func filter(_f: Callable) -> Option:
return self
func flatten() -> Option:
return self
func map(_fn: Callable) -> Option:
return self
func ok_or(err: Variant) -> Result:
return Result.err(err)
func ok_or_else(fn: Callable) -> Result:
return Result.err(fn.call())
func or_other(option: Option) -> Option:
return option
func inspect(_fn: Callable) -> Option:
return self
func is_some() -> bool:
return false
func is_none() -> bool:
return true
func unwrap() -> Variant:
assert(false, "Called unwrap() on a None value")
return null
func unwrap_or(default_value: Variant) -> Variant:
return default_value
func unwrap_or_else(fn: Callable) -> Variant:
return fn.call()
func xor_other(other: Option) -> Option:
if other.is_some():
return other
else:
return self