# kojima a small functional/monad library # Usage ## Example ```js import { Option, Some, None, Result, Ok, Err } from 'kojima' const maybe = Option.of('thing') maybe.isSome() // true const isnt = maybe.chain(None).map(_x => 'other') // None isnt.isSome() // false const result = Result.of('3:41am') result.isOk() // true result.chain(() => Err(new Error(-Infinity))) .map(_x => '4:10am') .chain(Ok) result.isErr() // true // crimes! None == None() // true ``` ## Documentation ### curry > (* -> a) -> (* -> a) Returns a curried equivalent of the provided function. ```js import { curry } from './curry.js' const add = (a, b, c) => a + b + c const curriedAdd = curry(add) const add1 = curriedAdd(1) const add3 = add1(2) const add4 = curriedAdd(2, 2) const six = add3(3) // 6 const eight = add4(2) // 7 const twelve = curriedAdd(4, 4, 4) // 12 ``` ### Option > Option\ = Some\ | None Represents a value which may not exist. #### Methods ##### of :: Option f => a -> f a > Option.of\(value: a) -> Option\ Creates a new `Some` from `T` ```js const some = Option.of(1) // Some(1) ``` ##### zero :: Option f => () -> f a > Option.zero() -> Option\<()\> Creates a new `None` ```js const none = Option.zero() // None ``` ##### chain :: Option m => m a ~> (a -> m b) -> m b > Option\.chain\(fn: (value: T) -> Option\) -> Option\ Transform a `Option` into `Option` by applying `fn(T) -> Option`. ```js const some = Option.of(1) const next = some.chain(x => Some(`value ${x}`)) // Some('value 1') None.chain(x => Some(`value ${x}`)) // None const none = some.chain(None) // None none.chain(() => Some(1)) // None ``` ##### map :: Option f => f a ~> (a -> b) -> f b > Option\.map\(fn: (value: T) -> U) -> Option\ ##### alt :: Option f => f a ~> f a -> f a > Option\.alt(other: Option\) -> Option\ Choose between either the first or second `Option` based on existence. ```js const some = Option.of(1) const none = Option.zero() some.alt(none) // Some(1) none.alt(some) // Some(1) some.alt(Some(2)) // Some(1) Some(2).alt(some) // Some(2) none.alt(None) // None None.alt(none) // None ``` ##### fold :: Option f => f a ~> ((b, a) -> b, b) -> b > Option\.fold\(fn: ((acc: U, value: T) -> U, initial: U) -> U) -> U Fold over a `Option`, accumulating the value. This is `unwrap_or_default` in Rust. ```js const some = Some(1) some.fold((acc, x) => x), 2) // 1 some.fold((acc, x) => acc), 2) // 2 const none = Option.zero() none.fold((acc, x) => x, 2) // 2 ``` ##### isSome :: Option f => () -> boolean > Option\.isSome() -> boolean Returns a boolean based on whether the Option is `Some` ```js Some(1).isSome() // true None.isSome() // false ``` ##### isNone :: Option f => () -> boolean > Option\.isNone() -> boolean Returns a boolean based on whether the Option is `None` ```js Some(1).isNone() // false None.isNone() // true ``` ### Result > Result = Ok\ | Err\ Represents the result of a computation which may fail. #### Methods ##### of :: Result f => a -> f a > Result.of\(value: a) -> Result\ Creates a new `Ok` from `T` ```js const ok = Result.of(1) // Ok(1) ``` ##### zero :: Result f => () -> f a > Result.zero() -> Result\<(), ()\> Creates a new `Err<()>` ```js const err = Result.zero() // Err<()>() ``` ##### chain :: Result m => m a ~> (a -> m b) -> m b > Result\.chain\(fn: (value: T) -> Result) -> Result\ Transform a `Result` into `Result` by applying `fn(T) -> Result`. ```js const ok = Result.of(1) const next = ok.chain(x => Ok(`value ${x}`)) // Ok('value 1') Err(0).chain(x => Ok(1)) // Err(0) const err = next.chain(() => Err(0)) // Err(0) err.chain(() => Ok(1)) // Err(0) ``` ##### map :: Result f => f a ~> (a -> b) -> f b > Result\.map\(fn: (value: T) -> U) -> Result\ Transform a `Result` into a `Result` by applying `fn(T) -> U` ```js const ok = Result.of(1) const next = ok.map(x => `value ${x}`) // Ok('value 1') Err(0).map(x => Ok(1)) // Err(0) ``` ##### alt :: Result f => f a ~> f a -> f a > Result\.alt(other: Result\) -> Result\ Choose between either the first or second `Result` based on success. ```js const ok = Result.of(1) const err = Result.zero() ok.alt(err) // Ok(1) err.alt(ok) // Ok(1) ok.alt(Ok(2)) // Ok(1) Ok(2).alt(ok) // Ok(2) err.alt(Err(new Error('wont see this'))) // Err<()>() Err(new Error('hi! :3')).alt(err) // Err(new Error('hi! :3')) ``` ##### fold :: Result f => f a ~> ((b, a) -> b, b) -> b > Result\.fold\(fn: ((acc: U, value: T) -> U, initial: U) -> U) -> U Fold over a `Result`, accumulating the value. This is `unwrap_or_default` in Rust. ```js const ok = Ok(1) ok.fold((acc, x) => x), 2) // 1 ok.fold((acc, x) => acc), 2) // 2 const err = Result.zero() err.fold((acc, x) => x, 2) // 2 ``` ##### bimap :: Result f => f a c ~> (a -> b, c -> d) -> f b d > Result\.bimap\(x: (value: T1) -> T2, y: (error: E1) -> E2) -> Result\ ```js const ok = Ok(1) ok.bimap( x => x + 1, y => y * 2 ) // Ok(2) const err = Err(4) err.bimap( x => x + 1, y => y * 2 ) // Err(8) ``` ##### isOk :: Result f => () -> boolean > Result\.isOk() -> boolean Returns a boolean based on whether the Result is `Ok` ```js Ok(1).isOk() // true Err(1).isOk() // false ``` ##### isErr :: Result f => () -> boolean > Result\.isErr() -> boolean Returns a boolean based on whether the Result is `Err` ```js Ok(1).isErr() // false Err(1).isErr() // true ```