gpt4 book ai didi

数据/集合中的 Racket 序列与内置序列

转载 作者:行者123 更新时间:2023-12-04 06:38:54 25 4
gpt4 key购买 nike

我一直在尝试使用 data/collection 中的一些接口(interface),到目前为止我非常喜欢它。具有不同 Racket 集合(如列表、流和序列)的通用接口(interface)非常方便——特别是考虑到这些类型的接口(interface)的多样性(list-*vector-*, string-*, stream-*, sequence-*, ... !).

但是这些接口(interface)是否与 Racket 中的内置序列配合得很好?具体来说,我遇到了这个错误:

(require data/collection)
(take 10 (in-cycle '(1 2 3)))

=>

; take: contract violation
; expected: sequence?
; given: #<sequence>
; in: the 2nd argument of
; (-> natural? sequence? sequence?)
; contract from:
; <pkgs>/collections-lib/data/collection/sequence.rkt
; blaming: top-level
; (assuming the contract is correct)
; at: <pkgs>/collections-lib/data/collection/sequence.rkt:53.3

函数 in-cycle 返回一个内置的“序列”,而 data/collections 提供的多态 take 期望它自己的特殊序列接口(interface)。

在这种特殊情况下,我可以手动定义一个流来替换内置的in-cycle,例如:

(define (in-cycle coll [i 0])
(stream-cons (nth coll (modulo i (length coll)))
(in-cycle coll (add1 i))))

... 这有效,但有一个 awful lot of built-in sequences defined所以我想知道是否有更好的,也许是标准/推荐的方法来处理这个问题。也就是说,我们是否可以根据 data/collection 中定义的序列来利用所有内置序列,就像后者包装其他现有序列(如列表和流)一样?

最佳答案

在进一步研究之后,我想我对 Racket 和 data/collection 中的序列有了更好的理解。我会尽量总结其他答案和评论中提出的所有要点,并包括我自己的学习。

Racket 序列,即内置的序列,旨在成为 generic interface对于所有有序集合,您可以使用 dict-* 函数来处理包括散列在内的任何字典类型。此外,还有许多方便的实用程序提供内置序列,以便在不同场景中轻松处理有序数据,例如从集合中获取的元素序列,或在某个输入端口接收到的输入序列,或序列从字典中获取的键值对——最后一个本质上不是“有序”集合,但可以通过使用内置序列接口(interface)将其视为一个集合。

因此我们可以认为内置序列具有双重目的:

  1. 作为有序数据的统一接口(interface),以及
  2. 通过在每种情况下提供自然的序列接口(interface)实现,方便在不同场景中使用序列。

现在,虽然内置序列在理论上旨在成为有序集合的统一接口(interface),但在实践中,由于它们的冗长性,它们并不是特别适用于此目的,例如sequence-takesequence-length 而不仅仅是我们用于列表的 takelength

data/collection 序列解决了这个缺点,因为它们的名称简短且规范,例如 take 而不是 sequence-take。此外,这些序列还提供了drop-in replacements。对于内置序列提供的许多序列实用程序,例如 cyclenaturals 而不是 in-cyclein-naturals,以及一个通用的 in 函数来导出任何序列的惰性版本以用于迭代(如 (in (naturals)))。这些 data/collection 版本由于不可变而通常更“行为良好”,而内置序列不能保证这一点。因此,在许多情况下,data/collection 序列可以被视为内置序列的替代品,主要接管内置序列的两个用途中的第一个。

也就是说,在你处理序列的地方,考虑使用data/collection序列代替内置序列,而不是>使用内置序列。

然而,关于第 (2) 点,以下是当前可作为数据/收集序列处理的类型:

  • 列出
  • 不可变哈希表
  • 不可变向量
  • 不可变哈希集
  • 不可变字典

( source )

这已经足够了,但还有更多场景可以推导出常识性序列。对于以上未涵盖的任何此类情况,内置序列实用程序仍然有用,例如 in-hashin-portdata/中没有类似物集合序列。通常,在许多情况下,我们可以轻松导出内置序列(请参阅实用程序 here),但不能导出 data/collection 序列。在这些特殊情况下,我们可以简单地将如此获得的内置序列通过sequence->stream转换为流,然后通过更简单的data/collection序列接口(interface)使用它,因为流可被视为任一类型的序列。

关于数据/集合中的 Racket 序列与内置序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56490303/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com