【问题标题】:Racket - expected: sequence? given: #<sequence> contract violation球拍 - 预期:顺序?给定:#<sequence> 违反合同
【发布时间】:2020-10-11 18:01:21
【问题描述】:

在球拍中使用生成器和模式匹配我在练习懒惰地解构集合时遇到了以下错误,我无法弄清楚错误是什么,也不知道为什么会发生。

  (require racket/match)
  (require racket/generator)
  (require data/collection)
  (sequence->list
   (in-generator
    (let recur ([seq '(1 2 3)])
      (match seq
        [(sequence) (void)]
        [(sequence next next-rest ...)
         (yield next)
         (recur next-rest)]))))

给我以下错误:

sequence->list: contract violation
  expected: sequence?
  given: #<sequence>
  in: the 1st argument of
      (-> sequence? (listof any/c))
  contract from: 
      <pkgs>/collections-lib/data/collection/collection.rkt
  blaming: /var/folders/g4/0st3r3c513n6ymf2nkw11ml40000gn/T/ob-racket-CFPotf
   (assuming the contract is correct)
  at: <pkgs>/collections-lib/data/collection/collection.rkt:64.3
  context...:
   /usr/local/Cellar/minimal-racket/7.7/share/racket/collects/racket/contract/private/blame.rkt:347:0: raise-blame-error
   /usr/local/Cellar/minimal-racket/7.7/share/racket/collects/racket/contract/combinator.rkt:324:9
   /usr/local/Cellar/minimal-racket/7.7/share/racket/collects/racket/contract/private/arrow-val-first.rkt:486:18
   "/var/folders/g4/0st3r3c513n6ymf2nkw11ml40000gn/T/ob-racket-CFPotf": [running body]
   temp35_0
   for-loop
   run-module-instance!
   perform-require!

没有生成器,如果我只是在做(cons next (recur next-rest)) 一切正常,所以它不应该与我的模式匹配代码有任何关系。但是话又说回来,我对生成器非常有信心,并且做过很多次这样的事情,只是没有模式匹配位。我很确定这应该工作,但不知道为什么我会收到这个错误,甚至不知道它意味着什么。

【问题讨论】:

    标签: pattern-matching scheme generator racket


    【解决方案1】:

    这是因为data/collection 中的序列 概念与racket 中的序列 略有不同。来自data/collectionsequence-&gt;list 函数并不总是适用于来自racketracket/generator 的序列,因此您需要改用来自racketsequence-&gt;list

    一种方法是避免从data/collection 导入sequence-&gt;list

    #lang racket
    (require racket/match)
    (require racket/generator)
    (require (except-in data/collection sequence->list))
    (sequence->list
     (in-generator
      (let recur ([seq '(1 2 3)])
        (match seq
          [(sequence) (void)]
          [(sequence next next-rest ...)
           (yield next)
           (recur next-rest)]))))
    

    这会产生 '(1 2 3) 而不是您遇到的错误。

    解决此问题的另一种方法是将 sequenceracket 概念转换为 data/collection 版本,该版本更接近 streamracket 概念.您可以使用sequence-&gt;stream 来执行此操作。

    #lang racket
    (require racket/match)
    (require racket/generator)
    (require data/collection)
    (sequence->list
     (sequence->stream
      (in-generator
       (let recur ([seq '(1 2 3)])
         (match seq
           [(sequence) (void)]
           [(sequence next next-rest ...)
            (yield next)
            (recur next-rest)])))))
    

    这也会产生'(1 2 3)

    sequence-&gt;listsequence-&gt;stream 似乎是多余的,但请把它想象成 data/collection-sequence-&gt;listracket-sequence-&gt;data/collection-sequence

    尽管必须携带两种不同的序列概念,而这两种概念都被称为“序列”,这有点不方便。如果您愿意,可以导入带有前缀的 data/collection 东西以将它们标记为单独的,例如 dc:

    #lang racket
    (require racket/match)
    (require racket/generator)
    (require (prefix-in dc: data/collection))
    (sequence->list
     (in-generator
      (let recur ([seq '(1 2 3)])
        (match seq
          [(dc:sequence) (void)]
          [(dc:sequence next next-rest ...)
           (yield next)
           (recur next-rest)]))))
    

    根据您项目的其余部分的外观,您可能需要不同的风格。

    【讨论】:

      猜你喜欢
      • 2016-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-04
      • 2020-09-07
      • 1970-01-01
      • 2021-01-07
      相关资源
      最近更新 更多