【问题标题】:Iterating on elements of Scheme-vector causes contract violation迭代 Scheme-vector 的元素会导致合同违约
【发布时间】:2012-11-26 23:15:38
【问题描述】:

我正在尝试编写一个函数来检查给定的输入是否包含除数字以外的任何字符。但是,我在 Scheme 下的 DrRacket 中得到了contract violation

代码如下:

一种将字符串分割成字符的方法:

(define (breaking str) (list->vector (string->list str)))

为数字创建一个向量:

(define myNumber (breaking "123498765")) 

在这里我检查给定的数字:

(define (vectorFunc myVector)
(define i 0)                      
(do ()                             
  ((= i (vector-length myVector))) ; run until the end of the vector
  (cond ((< (vector-ref myVector i) #\0) 'incorrect)
        ((> (vector-ref myVector i) #\9)  'also-incorrect))
  (set! i (+ i 1))    ; inc "i+ by 1
); end of do
)

(vectorFunc myNumber) 的输出是:

. . >: contract violation
  expected: real?
  given: #\1
  argument position: 1st
  other arguments...:
   #\0
> 

它有什么问题?

【问题讨论】:

    标签: string vector functional-programming scheme racket


    【解决方案1】:

    正如 Racket 正确告诉您的那样,您正在比较 cond-branch 中的苹果和橙子,即字符与实数; string-&gt;list 创建一个 chars 列表。你可以编写自己的谓词来克服这个问题并将它映射到一个向量上(这将是一个更实用的解决方案——你的代码看起来不像方案;))

    (define (breaking str)
      (list->vector (string->list str)))
    
    (define my-number
      (breaking "1234987650"))
    
    (define (represents-char-number? char)
      (if (member char '(#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9))
          #t
          #f))
    
    (define (vector-func vec)
      (vector-map represents-char-number? vec))
    
    (vector-func my-number)
    ===> #(#t #t #t #t #t #t #t #t #t #t)
    

    vector-map 在 R6RS 中是标准化的。也请考虑一些 style-rules 用于 lisp 家族的语言。

    【讨论】:

    • 别忘了#\0 char ;)
    【解决方案2】:

    如果您需要确定一个值是否是介于#\0#\9 之间的字符,最好使用char-numeric? 谓词:

    (char-numeric? a-char)
    

    来自文档:

    如果 char 具有 Unicode“数字”属性,则返回 #t。

    就您的代码而言,它看起来像这样:

    (cond ((not (char-numeric? (vector-ref myVector i)))
           'incorrect)
          (else ...))
    

    我同意@LudwigMeier 的评论 - 您的代码看起来不像 Scheme。您正在尝试将 Scheme 用作类似 C 的语言,它看起来有点奇怪。在 Scheme 中,事情已经完成了......不同。

    【讨论】:

    • 感谢char-numeric? 的提示! :)
    • @Óscar López:如果我运行(define myNumber (breaking "dsdsadsa")),那么我会得到char-numeric?: contract violation expected: char? given: 1
    • @Óscar López:好的,你赢了 :) 你的建议很有效! +1 并被选中!
    • @ron 真的吗?它对我有用,char-numeric? 只返回#f。你确定你将字符传递给谓词吗?错误表明您传递了数字1
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-21
    • 1970-01-01
    • 2015-11-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多