Scheme 生成列表(错误-需要一个过程)球拍/方案

Scheme 生成列表(错误-需要一个过程)球拍/方案,scheme,racket,Scheme,Racket,试图创建一个生成n×n板的函数 (new-board 2) 应该生产 (list (make-posn 0 0) (make-posn 0 1) (make-posn 1 0) (make-posn 1 1)) “我的代码”的当前格式副本如下: (define (new-board y) (build-list y (lambda (x) (build-list x (make-posn y x)))) ) ==> (build-list 5 (lambda (

试图创建一个生成n×n板的函数

(new-board 2)
应该生产

(list (make-posn 0 0) (make-posn 0 1) (make-posn 1 0) (make-posn 1 1))
“我的代码”的当前格式副本如下:

(define (new-board y)
    (build-list y (lambda (x) (build-list x (make-posn y x))))
      )
 ==> (build-list 5 (lambda (x) ...))
 ==> (list ( (lambda (x) (build-list ... x ...))  0 )
           ( (lambda (x) (build-list ... x ...))  1 )
           ( (lambda (x) (build-list ... x ...))  2 )
           ( (lambda (x) (build-list ... x ...))  3 )
           ( (lambda (x) (build-list ... x ...))  4 )
 ==> (list (build-list ... 0 ...)
           (build-list ... 1 ...)
           (build-list ... 2 ...)
           (build-list ... 3 ...)
           (build-list ... 4 ...))
我很确定它会起作用,但考虑到我目前在球拍方面的知识和经验,我找不到错误

我输入:

> (new-board 3)
并得到了错误信息:

build-list: expects a procedure (arity 1); given (make-posn 3 0)
通过调用构建列表中的构建列表,我是否犯下了令人发指的罪行? 请让我知道。谢谢

关于此过程:

(define (new-board y)
    (build-list y (lambda (x) (build-list x 
                                          (make-posn y x))))) ;error!
让我们看看什么作为参数接收。第一个参数是y,一个数字,第二个参数是一个过程,但是你要传递的是make posn的求值结果,它不是一个过程,而是一个值。这就是你犯错误的原因

编辑1:

现在我明白你的意图了。我可以想出一个解决方案,但比你想象的要详细一些:

(define (new-board n)
  (flatten
   (map (lambda (x)
          (map (lambda (y)
                 (make-posn x y))
               (build-list n identity)))
        (build-list n identity))))

(define (flatten lst)
  (if (not (list? lst))
      (list lst)
      (apply append (map flatten lst))))
下面是它的工作原理:

生成列表只是用于生成从0到n-1的数字,我将传递标识作为过程,因为每个数字不需要进一步处理 对于列表中的每个数字,我们还希望生成另一个列表,再次从0到n-1,因为电路板中的所有坐标都是必需的。例如,如果n为3,则坐标为“0 0 1 0 2 1 0 1 1 2 0 2 1 2 2 2 我正在使用映射中的一个映射来构建嵌套列表,这是一种借用自see:nested mappings的技术 最后,我必须展平生成的列表,这就是展平所做的,否则,我们将以列表列表结束 编辑2:

想想看,我找到了一个更简单的方法,更接近你的想法。请注意,展平过程是不可避免的:

(define (new-board n)
  (flatten
   (build-list n
               (lambda (x)
                 (build-list n
                             (lambda (y)
                               (make-posn x y)))))))
现在,当您键入以下内容时:

(new-board 2)
结果如预期:

(#(struct:posn 0 0) #(struct:posn 0 1) #(struct:posn 1 0) #(struct:posn 1 1))
关于此过程:

(define (new-board y)
    (build-list y (lambda (x) (build-list x 
                                          (make-posn y x))))) ;error!
让我们看看什么作为参数接收。第一个参数是y,一个数字,第二个参数是一个过程,但是你要传递的是make posn的求值结果,它不是一个过程,而是一个值。这就是你犯错误的原因

编辑1:

现在我明白你的意图了。我可以想出一个解决方案,但比你想象的要详细一些:

(define (new-board n)
  (flatten
   (map (lambda (x)
          (map (lambda (y)
                 (make-posn x y))
               (build-list n identity)))
        (build-list n identity))))

(define (flatten lst)
  (if (not (list? lst))
      (list lst)
      (apply append (map flatten lst))))
下面是它的工作原理:

生成列表只是用于生成从0到n-1的数字,我将传递标识作为过程,因为每个数字不需要进一步处理 对于列表中的每个数字,我们还希望生成另一个列表,再次从0到n-1,因为电路板中的所有坐标都是必需的。例如,如果n为3,则坐标为“0 0 1 0 2 1 0 1 1 2 0 2 1 2 2 2 我正在使用映射中的一个映射来构建嵌套列表,这是一种借用自see:nested mappings的技术 最后,我必须展平生成的列表,这就是展平所做的,否则,我们将以列表列表结束 编辑2:

想想看,我找到了一个更简单的方法,更接近你的想法。请注意,展平过程是不可避免的:

(define (new-board n)
  (flatten
   (build-list n
               (lambda (x)
                 (build-list n
                             (lambda (y)
                               (make-posn x y)))))))
现在,当您键入以下内容时:

(new-board 2)
结果如预期:

(#(struct:posn 0 0) #(struct:posn 0 1) #(struct:posn 1 0) #(struct:posn 1 1))

如果您查找构建列表的签名合同,您会看到它是

 build-list : Nat (Nat -> X) -> (listof X)
因此,它需要一个自然数,然后是一个函数,该函数需要一个自然数,并返回一个您希望包含在列表中的X类型的元素。所以在你们的例子中,你们希望X是什么样的具体类型,对于你们要建立的列表,它在每种情况下都是不同的。在内部构建列表的情况下,看起来您正在尝试创建POSN列表。然而,makeposnyx立即生成一个posn,并不像构建列表所期望的那样是一个函数。就像你提供一个函数λx一样。。。对于外部构建列表,您还应该提供一个函数lambda。。。内部功能

为第一个lambda的参数选择名称x可能有点混乱。我可能要做的是将新board函数的参数名称更改为N,因为您似乎想要创建一个包含N行和N列的board。第一个构建列表的目的是创建这些行或列中的每一行或每一列,这取决于您对它的想法。如果你有:

 (define (new-board N)
   (build-list N (lambda (x) ...)))
然后你会像这样使用它:

 (new-board 5)
它将减少/简化/评估如下:

(define (new-board y)
    (build-list y (lambda (x) (build-list x (make-posn y x))))
      )
 ==> (build-list 5 (lambda (x) ...))
 ==> (list ( (lambda (x) (build-list ... x ...))  0 )
           ( (lambda (x) (build-list ... x ...))  1 )
           ( (lambda (x) (build-list ... x ...))  2 )
           ( (lambda (x) (build-list ... x ...))  3 )
           ( (lambda (x) (build-list ... x ...))  4 )
 ==> (list (build-list ... 0 ...)
           (build-list ... 1 ...)
           (build-list ... 2 ...)
           (build-list ... 3 ...)
           (build-list ... 4 ...))

所以,嵌套构建列表并没有错。看看你现在是否能弄明白,一旦当前行被固定为一个特定的x值,如何让内部构建列表生成POSN列表。

如果你查找构建列表的签名契约,你会发现它是

 build-list : Nat (Nat -> X) -> (listof X)
因此,它需要一个自然数,然后是一个函数,该函数需要一个自然数,并返回一个您希望包含在列表中的X类型的元素。所以在你们的例子中,你们希望X是什么样的具体类型,对于你们要建立的列表,它在每种情况下都是不同的。在内部构建列表的情况下,看起来您正在尝试创建POSN列表。然而 makeposnyx立即生成一个posn,它不是构建列表所期望的函数。就像你提供一个函数λx一样。。。对于外部构建列表,您还应该提供一个函数lambda。。。内部功能

为第一个lambda的参数选择名称x可能有点混乱。我可能要做的是将新board函数的参数名称更改为N,因为您似乎想要创建一个包含N行和N列的board。第一个构建列表的目的是创建这些行或列中的每一行或每一列,这取决于您对它的想法。如果你有:

 (define (new-board N)
   (build-list N (lambda (x) ...)))
然后你会像这样使用它:

 (new-board 5)
它将减少/简化/评估如下:

(define (new-board y)
    (build-list y (lambda (x) (build-list x (make-posn y x))))
      )
 ==> (build-list 5 (lambda (x) ...))
 ==> (list ( (lambda (x) (build-list ... x ...))  0 )
           ( (lambda (x) (build-list ... x ...))  1 )
           ( (lambda (x) (build-list ... x ...))  2 )
           ( (lambda (x) (build-list ... x ...))  3 )
           ( (lambda (x) (build-list ... x ...))  4 )
 ==> (list (build-list ... 0 ...)
           (build-list ... 1 ...)
           (build-list ... 2 ...)
           (build-list ... 3 ...)
           (build-list ... 4 ...))

所以,嵌套构建列表并没有错。看看你现在是否能弄明白,一旦当前行被固定为一个特定的x值,如何让内部构建列表生成POSN列表。

顺便说一下,如果允许使用full Racket,有一种很好的方法可以用for循环来表示计算:

另一种获得相同结果但使用不同方法的方法是使用带有商和余数的算术技巧


顺便说一句,如果你被允许使用完整的球拍,有一个很好的方法来表达for循环的计算:

另一种获得相同结果但使用不同方法的方法是使用带有商和余数的算术技巧


啊,我想,把这个项目的整体意图漏掉是错误的。这是解决n皇后问题的前奏。虽然我还没有准备好这样做,因为我仍然无法在这个简单的程序中解决问题。是的,它应该产生一个POSN列表。虽然我完全明白你为什么要问这个P@WhiteBit无论如何,你应该发布构建列表的代码并制作posn,否则我们就被留在了darkAlso中,构建列表是一个内置函数。生成列表n进程→ list build list 5 add1将生成list 1 2 3 4 5//make posn创建一个带有两个num的结构posn。我通常将其用作关联数组,但这次它用于表示板上的瓷砖。@WhiteBit我忽略了这一事实。我编辑了我的答案,现在错误清楚了。请发布make posn,还有一个例子,你希望从新的电路板上得到什么样的输出-列表make posn 0 make posn 0 1 make posn 1 0 make posn 1 1或是对列表中每个元素make posn 1 1的评估结果我认为make posn听起来如此陌生的原因可能是它只在如何设计程序的初级学生中引入了-计划好吧,让我们来做一个posn。制作posn:number-number->posn。可能是这样定义的:定义struct posn x y,其中x和y是数字。希望这能把事情弄清楚。谢谢你的时间,奥斯卡!啊,我想,把这个项目的整体意图漏掉是错误的。这是解决n皇后问题的前奏。虽然我还没有准备好这样做,因为我仍然无法在这个简单的程序中解决问题。是的,它应该产生一个POSN列表。虽然我完全明白你为什么要问这个P@WhiteBit无论如何,你应该发布构建列表的代码并制作posn,否则我们就被留在了darkAlso中,构建列表是一个内置函数。生成列表n进程→ list build list 5 add1将生成list 1 2 3 4 5//make posn创建一个带有两个num的结构posn。我通常将其用作关联数组,但这次它用于表示板上的瓷砖。@WhiteBit我忽略了这一事实。我编辑了我的答案,现在错误清楚了。请发布make posn,还有一个例子,你希望从新的电路板上得到什么样的输出-列表make posn 0 make posn 0 1 make posn 1 0 make posn 1 1或是对列表中每个元素make posn 1 1的评估结果我认为make posn听起来如此陌生的原因可能是它只在如何设计程序的初级学生中引入了-计划好吧,让我们来做一个posn。制作posn:number-number->posn。可能是这样定义的:定义struct posn x y,其中x和y是数字。希望这能把事情弄清楚。谢谢你的时间,奥斯卡!