Option.bruijn
# MIT License, Copyright (c) 2022 Marvin Borner
# TODO: move to monad?
:import std/Combinator .
:import std/Logic .
# empty option
none true ⧗ (Option a)
# encapsulates value in option
some [[[0 2]]] ⧗ a → (Option a)
# checks whether option is none
none? [0 true [false]] ⧗ (Option a) → Boolean
:test (none? none) (true)
:test (none? (some [[0]])) (false)
# checks whether option is some
some? [0 false [true]] ⧗ (Option a) → Boolean
:test (some? none) (false)
:test (some? (some [[0]])) (true)
# applies a function to the value in option
map [[0 none [some (2 0)]]] ⧗ (a → b) → (Option a) → (Option b)
:test (map [[1]] (some [[0]])) (some [[[0]]])
:test (map [[1]] none) (none)
# applies a function to the value in option or returns first arg if none
map-or v ⧗ a → (b → c) → (Option b) → c
:test (map-or [[[2]]] [[1]] (some [[0]])) ([[[0]]])
:test (map-or [[[2]]] [[1]] none) ([[[2]]])
# extracts value from option or returns first argument if none
unwrap-or [[0 1 i]] ⧗ a → (Option b) → c
:test (unwrap-or false (some true)) (true)
:test (unwrap-or false none) (false)
# applies encapsulated value to given function
apply [[1 none 0]] ⧗ (Option a) → (a → b) → c
:test (apply none [some ([[1]] 0)]) (none)
:test (apply (some [[0]]) [some ([[1]] 0)]) (some [[[0]]])
result-or [[0 [[0 3]] [[[1 2]]]]]
:test (result-or "fail" none) ([[0 "fail"]])
:test (result-or "fail" (some "ok")) ([[1 "ok"]])
pure some ⧗ a → (Option a)
bind [[1 1 0]] ⧗ (Option a) → (a → (Option b)) → (Option a)
…>>=… bind
:test (none >>= (pure "idk")) (none)
:test ((some 'a') >>= [pure [1]]) (some ['a'])