for循环中的多个绑定

时间:2016-05-26 19:41:46

标签: for-loop racket

因此,Racket(6.5)文档说您可以同时绑定多个ID:

(for ([(i j) #hash(("a" . 1) ("b" . 20))])
    (display (list i j)))

Bu-u-ut我无法弄清楚/找到如何使用手动构建的数据执行此操作的示例:

(define a '(1 2 3 4 5))
(define b '(10 20 30 40 50))
(for ([(i j) (map list a b)])
    (display (list i j)))

爆炸
result arity mismatch;
 expected number of values not received
  expected: 2
  received: 1
  from: 
  in: local-binding form
  values...:

我错过了什么?

2 个答案:

答案 0 :(得分:5)

在此示例中,您可以使用单独的子句绑定ij

(for ([i (list 1 2 3 4 5)]
      [j (list 10 20 30 40 50)])
  (display (list i j)))

更一般地说,您可以使用in-parallel从单个值的多个序列创建多个值的单个序列:

(for ([(i j) (in-parallel (list 1 2 3 4 5)
                          (list 10 20 30 40 50))])
    (display (list i j)))

两种解决方案都打印(1 10)(2 20)(3 30)(4 40)(5 50)

答案 1 :(得分:5)

(for ([(i j) #hash(("a" . 1) ("b" . 20))])
    (display (list i j)))

的缩写
(for ([(i j) (in-hash #hash(("a" . 1) ("b" . 20)))])
    (display (list i j)))

现在in-hash一次返回两个值,因此(i j) 将受到这两个值的约束。

另一方面,这个:

(for ([(i j) (map list a b)])
    (display (list i j)))

的缩写
(for ([(i j) (in-list (map list a b))])
    (display (list i j)))

in-list将一次返回一个元素(在您的示例中) 元素是一个列表)。由于(i j)中有两个名称 而不只是一个,发出错误信号。

in-parallel中关注Toxaris的建议。

更新

以下助手make-values-sequence显示 如何重复创建自定义序列 产生多个值。

#lang racket

(define (make-values-sequence xss)
  ; xss is a list of (list x ...)
  (make-do-sequence (λ ()
                      (values (λ (xss) (apply values (first xss))) ;  pos->element
                              rest                                 ;  next-position
                              xss                                  ;  initial pos
                              (λ (xss) (not (empty? xss)))         ;  continue-with-pos?
                              #f                                   ;  not used
                              #f))))                               ;  not used]


(for/list ([(i j) (make-values-sequence '((1 2) (4 5) (5 6)))])
  (+ i j))

输出:

'(3 9 11)