Carp/core/Control.carp
Scott Olsen d8d3669a16
feat: add 'when' functions for Maybe and Result (#1180)
* feat: add 'when' functions for Maybe and Result

These functions enable users to execute some side-effecting function
(one that returns unit and take no arguments) based on the contents of a
Maybe or Result.

`when-success`: Executes a side-effect when given a `Result.Success`
`when-error`: Executes a side-effect when given a `Result.Error`
`when-just`: Executes a side-effect when given a `Maybe.Just`
`when-nothing`: Executes a side-effect when given a `Maybe.Nothing`

* docs: add Control to core lib doc generation
2021-03-15 09:53:22 +01:00

89 lines
2.7 KiB
Plaintext

;; This module contains functions that deal with functions, control flow, etc.
(defmodule Control
(doc iterate "Apply function `f` `n` times, first to `start` and then to the result of `f`. TODO: Mention fix points.")
(sig iterate (Fn [Int, (Ref (Fn [a] a b) c), a] a))
(defn iterate [n f start]
(let-do [result start]
(for [i 0 n]
(set! result (~f result)))
result))
(doc iterate-until "Like `iterate`, but f is applied repeatedly until the predicate `pred` is true.")
(sig iterate-until (Fn [(Ref (Fn [b] b c) d), (Ref (Fn [b] Bool c) e), b] b))
(defn iterate-until [f pred start]
(let-do [result start]
(while (not (~pred result))
(set! result (~f result)))
result))
(doc when-success
"Executes a side effect, `f`, when `result` is `Success`ful."
"```"
"(def suc (the (Result Int Int) (Result.Success 0)))"
"(def err (the (Result Int Int) (Result.Error 0)))"
""
"(when-success &(fn [] (IO.println \"success!\")) suc)"
"=> success!"
"(when-success &(fn [] (IO.println \"success!\")) err)"
"=> "
"```")
(sig when-success (Fn [&(Fn [] ()) (Result a b)] ()))
(defn when-success [f result]
(match result
(Result.Success _) (~f)
_ ()))
(doc when-error
"Executes a side effect, `f`, when `result` is `Error`oneus."
"```"
"(def suc (the (Result Int Int) (Result.Success 0)))"
"(def err (the (Result Int Int) (Result.Error 0)))"
""
"(when-error &(fn [] (IO.println \"error!\")) err)"
"=> error!"
"(when-error &(fn [] (IO.println \"error!\")) suc)"
"=> "
"```")
(sig when-error (Fn [&(Fn [] ()) (Result a b)] ()))
(defn when-error [f result]
(match result
(Result.Error _) (~f)
_ ()))
(doc when-just
"Executes a side-effect, `f`, when `maybe` is `Just`."
"```"
"(def just (Maybe.Just 2))"
"(def nothing (the (Maybe Int) (Maybe.Nothing)))"
""
"(when-just &(fn [] (IO.println \"just!\")) just)"
"=> just!"
"(when-just &(fn [] (IO.println \"just!\")) nothing)"
"=> "
"```")
(sig when-just (Fn [&(Fn [] ()) (Maybe a)] ()))
(defn when-just [f maybe]
(match maybe
(Maybe.Just _) (~f)
_ ()))
(doc when-nothing
"Executes a side-effect, `f`, when `maybe` is `Nothing`."
"```"
"(def just (Maybe.Just 2))"
"(def nothing (the (Maybe Int) (Maybe.Nothing)))"
""
"(when-nothing &(fn [] (IO.println \"nothing!\")) nothing)"
"=> nothing!"
"(when-nothing &(fn [] (IO.println \"nothing!\")) just)"
"=> "
"```")
(sig when-nothing (Fn [&(Fn [] ()) (Maybe a)] ()))
(defn when-nothing [f maybe]
(match maybe
(Maybe.Nothing) (~f)
_ ()))
)