你如何与拉基特的警卫配合



在Scala中,您可以执行以下操作:

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)
}

有可能使用Racket的match形式来做这样的事情吗?我在文档中找不到它

对于那些不熟悉Scala的人来说,如果数字等于或小于0,则第一种情况匹配,第二种情况只是一个通配符,它匹配其他所有

换言之,我将在???点中写些什么来实现与上述类似的功能?

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

Racket的match有一个可选的#:when子句,它可以让你像在Scala:中一样编写它

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

我认为这确实回答了你的问题。但更惯用的Racket是使用cond进行类似的测试——这是一个简单的条件测试,不需要任何破坏:

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

尽管我可能会改变主意:

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

当然,对于如此简单的事情,你可以使用if:

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

然而,我越来越喜欢使用cond,正如Racket风格指南所建议的那样。

原来我看得不够仔细,答案是:

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

(? expr patt)定义了一个保护。

以上内容可以更简洁地写成:

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

相关内容

  • 没有找到相关文章

最新更新