How do you feel about the guards at Racket?

In Scala, you can do something like this:

def times[A](item: A, number: Int): List[A] = number match {
  case n if n <= 0 => Nil // Nil = '()
  case _ => 
    // equivalent to [_ (cons item (times item (- number 1)))]
    item :: times(item, number - 1)
}

      

Can you do something like this with a Racket Form match

? I couldn't find it in the documentation

For those unfamiliar with Scala, the first case is the same if the number is equal to or less than 0, the second case is just a wildcard that matches everything else

In other words, what would I write in ???

place to achieve similar functionality than what I described above?

(define (times item number)
  (match number
    [??? '()]
    [_ (cons item (times item (- number 1)))]))

      

+3


source to share


2 answers


Racket match

has an optional clause #:when

that lets you write this in much the same way you did in Scala:

(define (times item number)
  (match number
    [n #:when (<= n 0) '()]
    [_ (cons item (times item (- number 1)))]))

      

I think this answers your question literally. But the more idiomatic Racket will use cond

for something like this - where it's a simple conditional test and you don't need any destructuring:

(define (times item number)
  (cond [(<= number 0) '()]
        [else (cons item (times item (- number 1)))]))

      

Though I would probably flip my arms around:



(define (times item number)
  (cond [(positive? number) (cons item (times item (- number 1)))]
        [else '()]))

      

Of course, for something this simple, you could use if

:

(define (times item number)
  (if (positive? number)
      (cons item (times item (- number 1)))
      '()))

      

However, I prefer to use cond

, as the Racket style guide recommends.

+3


source


Turns out I didn't look heavy enough, here's the answer:

(define (times item number)
  (match number
    [(? (lambda (n) (<= n 0))) '()]
    [_ (cons item (times item (- number 1)))]))

      

(? expr patt)

defines the guard.



The above could be more succinctly written as:

(define (lteq-0? n) (<= n 0))

(define (times item number)
  (match number
    [(? lteq-0?) '()]
    [_ (cons item (times item (- number 1)))]))

      

+1


source







All Articles