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)))]))
source to share
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.
source to share
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)))]))
source to share