【问题标题】:Getting #stream as an output in Drracket在 Drracket 中获取#stream 作为输出
【发布时间】:2016-01-12 03:39:21
【问题描述】:

给出了订单和数据流,我需要根据order-stream对数据进行排序。

#lang racket
(define the-empty-stream '())
(define (stream-car stream)
 (car stream))
(define-syntax cons-stream
 (syntax-rules ()
    ((cons-stream x y)
     (cons x (delay y)))))

(define (stream-cdr stream)
 (force (cdr stream)))
(define stream-null? null?)
(define (integers-starting-from n)
 (stream-cons n (integers-starting-from (+ n 1))))

(define integers (integers-starting-from 1))

(define order-stream (stream-cons 2 1))
(define data-stream (stream-cons 5 6))

(define (reorder order-stream data-stream)
 (cond ((stream-null? order-stream) the-empty-stream)
       ((stream-null? data-stream) the-empty-stream)
       (else (stream-cons (stream-ref data-stream 
                                      (stream-car order-stream))
                          (reorder (stream-cdr order-stream) data-stream)))))

当我执行(reorder order-stream data-stream) 时,我得到#stream 作为输出而不是6 . #promise。这是我的编程任务,所以不要给出完整的代码,而是给出一些提示。

【问题讨论】:

    标签: stream scheme racket


    【解决方案1】:

    看看你有什么:

    (define (reorder order-stream data-stream)
                     ^^^^^^^^^^^^
     (cond ((stream-null? order-stream) the-empty-stream)
           ((stream-null? data-stream) the-empty-stream)
           (else (stream-cons (stream-ref data-stream 
                                          (stream-car order-stream))
                              (reorder (stream-cdr order-stream) data-stream)))))
                                       ^^^^^^^^^^^^^^^^^^^^^^^^^
    
    (define (stream-cdr stream)
     (force (cdr stream)))
    

    (stream-cdr stream)预计会返回什么样的东西?

    然后你打电话

    (define order-stream (cons-stream 2 1))
    

    order-streamcdr 是什么?


    流式编程很有趣。例如,要计算流的部分和,p-s [a,b,c...] = a, a+b, a+b+c, ...,我们可以这样写

    (define (partial-sums xs init)
        (cons-stream init 
             (partial-sums (stream-cdr xs)
                           (+ (stream-car xs) init))))
    

    我们可以很容易地将+抽象为一个通用的二元运算参数:

    (define (scanl + xs init)
        (cons-stream init 
                  (scanl + (stream-cdr xs)
                           (+ (stream-car xs) init))))
    

    并将其称为,例如

    (define factorials (scanl * integers 1))
    

    另一种有趣定义scanl的方式是

    (define (scanlist + xs init)
       (define rs (cons-stream init 
                    (combine-streams + xs rs)))
       rs)
    

    编写 combine-streams(在 Haskell 中也称为 zipWith)是一个简单的交易。

    在 Racket 中,一定要使用完整的语言,其中define 是递归的,类似于letrec(不是let),否则最后一个将不起作用(你明白为什么吗?)。

    【讨论】:

    • Order-stream 是一个数字流,例如 2 3 4 1.... 这些数字是数据流的顺序,例如 5 6 7 8 ... 输出将是 6 7 8 1.. 这是重新排序的形式......所以这种情况下 order-stream 的 cdr 是 3
    • 不,它不是如所写的那样。 (cons-stream 2 1) = (cons 2 (delay 1)) = '(2 . 1)。这不是流。 (cons 2 (delay the-empty-stream)) 是一个流:它的stream-cdr 是一个流1 不是流。看reorder的定义。突出显示的片段表示流的stream-cdr必须是流。
    • 哦,我现在明白了,我对重新排序的定义是正确的,但我创建的流是错误的,你能否告诉我创建包含更多元素的流的方法。使用 cons 似乎更乏味 .. 感谢您的帮助,祝您有美好的一天
    • 是的,给自己写一个函数list-to-stream。这很容易。创建一个无限流,做一些专门的函数,比如integers-from-by x d = x, x+d, x+d+d, ...;同样流行的是partial-sums(或抽象+作为一般操作参数)和Haskell的iterate f x = x, f(x), f(f(x)), ...。考虑投票并接受对您最有帮助的答案。 :) 接受会给你 +2 代表,并且在代表 15 时,你可以对答案进行投票。 :)
    【解决方案2】:

    Racket 有一个内置的 stream-cons,您不小心调用了它,而不是您打算使用的 cons-stream

    【讨论】:

    • 当我使用 cons-stream 时,我收到类似 stream-ref: 合同违反预期的错误:流?给定:'(5 .#<...desktop>
    猜你喜欢
    • 2013-05-14
    • 1970-01-01
    • 1970-01-01
    • 2014-11-25
    • 1970-01-01
    • 2018-10-12
    • 2020-10-10
    • 2012-01-23
    • 2014-08-29
    相关资源
    最近更新 更多