PasteRack.org
Paste # 59103
2023-05-05 22:34:29

Fork as a new paste.

Paste viewed 1340 times.


Embed:

for/fold executing body

  1. #lang racket
  2.  
  3. (define (opt-for-paren paren-char)
  4.   (cond [(equal? paren-char #\()
  5.          (lambda (acc)
  6.            (+ acc 1))]
  7.         [(equal? paren-char #\))
  8.          (lambda (acc)
  9.            (- acc 1))]))
  10.  
  11. ;; Returns the 1-indexed position of the first thing that takes the "balance" to -1
  12. (define (unbalanced-pos stop paren-string)
  13.   (letrec ([balance-until
  14.             (lambda (stop paren-string)
  15.               (for/fold ([acc 0]
  16.                          [i 1])
  17.                         ([paren-char (in-string paren-string)]
  18.                          #:unless (equal? stop acc))
  19.                 (let* ([opt (opt-for-paren paren-char)]
  20.                        [new-balance (apply opt (list  acc))])
  21.                   ;; This feels gross - but is off by 1 otherwise b/c the call
  22.                   ;; to add1
  23.                   (if (equal? stop new-balance)
  24.                       (values new-balance i)
  25.                       (values new-balance
  26.                               (add1 i))))))])
  27.     (let-values ([(balance imbalance-pos)
  28.                   (balance-until stop paren-string)])
  29.       (if (equal? balance stop) imbalance-pos -1))))
  30.  
  31. (unbalaced-pos -1 ")())())") ; 1

=>

unbalaced-pos: undefined;

 cannot reference an identifier before its definition

  in module: 'm