Skip to content

Commit

Permalink
Add `-npartial' for arbitrary partial application
Browse files Browse the repository at this point in the history
Currently, we have `-partial' and `-rpartial' for currying with
arguments at either the left or the right.

`-npartial' is a generalisation of `-partial' and `-rpartial'. It takes
an offset N to determine where to put the curried arguments, a function
FN, and the partially applied ARGS.

ARGS will be spliced in after the Nth element in the additional args. If
N is negative, -1 is taken to be the final item, -2, the penultimate
item, etc.

This function satisfies the following laws:

  (-npartial 0 ...) ≡ (-partial ...)
  (-npartial -1 ...) ≡ (-rpartial ...)"

E.g.:
  (funcall (-npartial 1 (lambda (a b c) (+ a (* b c))) 5)
      2 3) ;; => 17
  (funcall (-npartial 2 (lambda (a b c d) (+ a (* b c) d)) 3)
      2 4 5) ;; => 19
  (funcall (-npartial -1 #'concat "last " "words.")
      "These " "are " "the ") ;; => "These are the last words."
  (funcall (-npartial 3 (lambda (a b c d e f) (concat a b c d e f "."))
                      "penultimate " "words ")
      "I'll " "put " "the " "here")
  ;; => "I'll put the penultimate words here."
  • Loading branch information
daantjie committed Nov 13, 2016
1 parent 07c61f5 commit d8666e1
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 0 deletions.
22 changes: 22 additions & 0 deletions dash-functional.el
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,28 @@ When called, the returned function calls FN with the additional
args first and then ARGS."
(lambda (&rest args-before) (apply fn (append args-before args))))

(defun -npartial (n fn &rest args)
"Takes an offset N, a function FN and fewer than the normal
arguments to FN, and returns a function which takes a variable
number of additional ARGS, similar to `-partial' and
`-rpartial'.
ARGS will be spliced in after the Nth element in the additional
args. If N is negative, -1 is taken to be the final item, -2, the
penultimate item, etc.
This function satisfies the following laws:
(-npartial 0 ...) ≡ (-partial ...)
(-npartial -1 ...) ≡ (-rpartial ...)"
(lambda (&rest args-around) (apply fn (if (< n 0)
(append (-drop-last (1+ n) args-around)
args
(-take-last (1+ n) args-around))
(append (-take n args-around)
args
(-drop n args-around))))))

(defun -juxt (&rest fns)
"Takes a list of functions and returns a fn that is the
juxtaposition of those fns. The returned fn takes a variable
Expand Down
6 changes: 6 additions & 0 deletions dev/examples.el
Original file line number Diff line number Diff line change
Expand Up @@ -1055,6 +1055,12 @@ new list."
(funcall (-rpartial '- 5) 8) => 3
(funcall (-rpartial '- 5 2) 10) => 3)

(defexamples -npartial
(funcall (-npartial 1 (lambda (a b c) (+ a (* b c))) 5) 2 3) => 17
(funcall (-npartial 2 (lambda (a b c d) (+ a (* b c) d)) 3) 2 4 5) => 19
(funcall (-npartial -1 #'concat "last " "words.") "These " "are " "the ") => "These are the last words."
(funcall (-npartial 3 (lambda (a b c d e f) (concat a b c d e f ".")) "penultimate " "words ") "I'll " "put " "the " "here") => "I'll put the penultimate words here.")

(defexamples -juxt
(funcall (-juxt '+ '-) 3 5) => '(8 -2)
(-map (-juxt 'identity 'square) '(1 2 3)) => '((1 1) (2 4) (3 9)))
Expand Down

0 comments on commit d8666e1

Please sign in to comment.