Added combinator functions: `combine{,1,!}()` and `inverse{,*}()`.

Fortune for cl-utils's current commit: Middle blessing − 中吉
master
Avril 2 years ago
parent 32590769af
commit 13e7b09b24
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -107,6 +107,8 @@
(defun true (f)
(not (null f)))
; Functional
(defun nop ()
"Do nothing"
nil)
@ -115,6 +117,42 @@
"Do nothing"
t)
; Combinators
(defun deatomise (list)
"If `list' is a list, pass it through; if it is a non-nil atom, wrap it in a single-element list"
(if (and list (atom list))
(cons list nil)
list))
(defun deatomise! (list) "Ensure `list' is a list" (cons list nil))
(defun combine (fa fb &key (pass #'deatomise!))
"Returns an applicative lambda that runs (`fb' (`fa' args...)...)
NOTE: This function *applies* the result of `fa' to `fb', therefore, if the result of `fa' is a list, the elements of said list are applied as the sequential arguments for `fb', if the result is a single element, it is passed as argument 1 only (this includes ``nil''). If you want to pass the result of `fa' to `fb' verbatim through the first argument only, use ``combine1''().
WARNING: By default, if `fa' returns ``nil'', the ``nil'' is passed as argument 1 to `fb'. Therefore, no function `fa' will ever produce 0 arguments for `fb'; if you wish to override this behaviour and allow a nil return to mean 0 arguments, set `pass' to ``deatomise''() (to still ensure the return of `fa' is contained list; you can use ``combine!''() for behaviour instead too), or the ``identity''() function, if you know `fa' returns a list."
(lambda (&rest args) (apply fb (funcall pass (apply fa args)))))
(defun combine! (fa fb)
"Returns an applicative lambda that runs (`fb' [(`fa' args...)...])
NOTE: This is the same as calling `combine' with `pass' as ``deatomise''()."
(combine fa fb :pass #'deatomise))
(defun combine1 (fa fb)
"Returns a lambda that runs (`fb' (`fa' args...))
NOTE: The difference between this an ``combine''() is that `combine' *applies* the result of `fa' to `fb', whereas `combine1'() simply calls `fb' with the result of `fa'."
(lambda (&rest args) (funcall fb (apply fa args))))
(defun inverse (func)
"Returns a lambda that resolves ¬(`func' args...)"
(lambda (&rest n) (not (apply func n))))
(defun inverse* (&rest functions)
"Returns a list of `inverse'()d functions from `functions'"
(mapcar #'inverse functions))
;; Mapping
(defun mapline (input fi &key (read-line #'read-line))
"Map lines from stream"
(loop for line = (funcall read-line input nil)

Loading…
Cancel
Save