Carp/core/Control.carp
2021-07-05 14:48:35 +02:00

91 lines
2.8 KiB
Plaintext

;; This module contains functions that deal with functions, control flow, etc.
(doc Control "contains functions that deal with functions, control flow, and
other higher order concepts.")
(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)
_ ()))
)