我执行“地图”时违反合同

时间:2016-07-11 17:16:53

标签: scheme racket

我开始使用Scheme(实际上是带有DrRacket的Racket),我希望通过实现map函数来练习(将函数应用于列表的所有元素),但是有些错误我不明白。 (除了我的命令背景,我有haskell的基本知识)

我想翻译下面的haskell(只是为了显示算法):

map f [] = []
map f x:xs = (f x) : (map f xs)

这是我的代码:

(define (map f xs)

  (if (= xs '()) '() ; if list is empty, return empty list
      (cons (f (car xs)) (map f (cdr xs))))

  )

为了测试它,我使用了这个:

(define (testFunction x) (+ x 1))
(define testList '(1 2 3 4 5))
(map testFunction testList)

我收到以下错误:

  

=:合同违规
  预期:数字?
  给出:'(1 2 3 4 5)
  论点位置:1   其他论点......:

突出显示谓词(= xs'())

任何提示?

3 个答案:

答案 0 :(得分:3)

=函数专门用于数字之间的相等。它通过处理精确数字和不精确数字之间的比较,对数值进行特殊处理。但是,一般而言,对于非数字相等,您应该使用equal?谓词:

> (equal? '() '())
#t

在这种特殊情况下,如Raghav所述,您还可以使用empty?null?来测试空列表(empty?谓词只是别名null?)。

答案 1 :(得分:3)

哇 - 其他一些人已经打败了我,但我还是会分享我的答案。

您的问题源于您使用=来测试列表空虚。

来自the docs中的=

  

如果所有参数在数值上相等,则返回#t,#f   否则。

为了让您的程序正常运行,我建议您使用equal?来测试两个列表是否相等,或者更好的是,使用empty?null?来测试xs是一个空列表。 (我希望你不要冒犯,但我也将这些代码按照可以说是更为惯用的方案进行了按摩。

(define (mymap f xs)
  (if (empty? xs)
    xs
    (cons 
      (f (car xs))
      (mymap f (cdr xs)))))

(define (test-function x) (+ x 1))
(define test-list (list 1 2 3 4))

(mymap test-function test-list)

答案 2 :(得分:2)

如果你正在使用DrRacket,那么对于那个条件,只需使用(空?):

(if (empty? xs)
    xs ; because xs is empty
    ...)