agj · GitHub

Macro

Defines an automatically currying procedure in a single step. Uses curry internally.

(begin-for-syntax
  (define-syntax-class name-params
    #:description "name and parameters clause"
    (pattern (name:id params:id ...+)
             #:fail-when (check-duplicate-identifier
                          (syntax->list #'(params ...)))
             "duplicate parameter name")))
(define-syntax (define/curry stx)
  (syntax-parse stx
    [(_ np:name-params body ...+)
     #`(define np.name
         (curry #,(syntax/loc stx
                    (λ (np.params ...)
                      body ...))))]))

Example

;; Define a procedure like this:
(define/curry (insert-between mid left right)
  (string-join (list left mid right) ""))
;; To use it like this:
(define dash-between (insert-between "-"))
(dash-between "left" "right") ; "left-right"
;; Or currying wherever necessary:
(((insert-between "-") "left") "right") ; "left-right"

Before and After

This code-cleaning macro reduces some boilerplate necessary to define a curried function. Code like this:

(define insert-between
  (curry
   (λ (mid left right)
     (string-join (list left mid right) ""))))

Is simplified to this, identical in form to defining a regular procedure:

(define/curry (insert-between mid left right)
  (string-join (list left mid right) ""))

I wrote an earlier version of this macro when implementing some Haskell code in Racket, and thought it was useful enough to share!

Licence

I release the above code under the MIT license, and accompanying text under the Creative Commons Attribution 4.0 International license.

Read the original on github.com ↗