Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scheme 为什么apply map and to list of expressions只返回一个布尔值?_Scheme_Racket - Fatal编程技术网

Scheme 为什么apply map and to list of expressions只返回一个布尔值?

Scheme 为什么apply map and to list of expressions只返回一个布尔值?,scheme,racket,Scheme,Racket,为什么:(应用map和-l(gentruth 2'(#t#f)) 返回”(#f#f)?我希望它为包含布尔值对的每个子表达式返回一个布尔值。 更好的和-l程序 问题在于和-l程序的运行方式可能出乎意料。这里,x在传递到过程主体之前被放入一个列表中。考虑: scratch.rkt>(定义坏程序(lambda x)) scratch.rkt>(错误处理’(#t#f)) “(#t#f)) 人们可能会期望和-l过程测试列表是否包含所有真值,而传递到过程主体的过程会: scratch.rkt>(和-l-

为什么:
(应用map和-l(gentruth 2'(#t#f))

返回
”(#f#f)
?我希望它为包含布尔值对的每个子表达式返回一个布尔值。


更好的
和-l
程序
问题在于
和-l
程序的运行方式可能出乎意料。这里,
x
在传递到过程主体之前被放入一个列表中。考虑:

scratch.rkt>(定义坏程序(lambda x))
scratch.rkt>(错误处理’(#t#f))
“(#t#f))
人们可能会期望
和-l
过程测试列表是否包含所有真值,而传递到过程主体的过程会:

scratch.rkt>(和-l-bad'(#t#f))
#t
scratch.rkt>(和-l-bad'(#f#f))
#t
scratch.rkt>(和-l-bad'(#t#t))
#t
这是
和-l
的正确版本;请注意,不需要
应用

(define (cart . lists)
  (cond ((null? lists) '())
        ((= (length lists) 1) (map list (first lists)))
        (else
         (append-map (lambda(x)
                       (map (lambda(y) (cons y x))
                            (first lists)))
                     (apply cart (rest lists))))))

(define (numbers n)
   (define (reversed-numbers n)
     (if (= n 0)
         '()
         `(,n . ,(reversed-numbers (- n 1)))))
   (reverse (reversed-numbers n)))

(define (gen-truth n vals)
       (apply cart (map (lambda(x) list vals) (numbers n))))

(gen-truth 2 '(#t #f))  returns: '((#t #t) (#f #t) (#t #f) (#f #f))

(define and-l (lambda x 
    (if (null? x)
        #t
        (if (car x) (apply and-l (cdr x)) #f))))
测试新程序:

scratch.rkt>(and-l'(#t#f))
#f
scratch.rkt>(and-l'(#f#f))
#f
scratch.rkt>(and-l'(#t#t))
#t
现在,
和-l
正在正常工作,我们将注意力转向:

(define and-l
  (lambda (x)
    (if (null? x)
        #t
        (and (car x) (and-l (cdr x))))))
同样,这里不需要
apply
。在这里执行
(apply map and-l;…)
甚至没有意义。
apply
过程将过程和列表作为参数,并使用列表中的元素作为过程的参数。因此,
(apply+'(1234))
相当于
(+1234)
。在当前环境中不需要这种能力;只需将
map
应用于
和-l
gen truth
返回的列表中的每个布尔值列表:

scratch.rkt>(gen truth 2'(#t#f))
“(#t#t)(#f#t)(#t#f)(#f#f))
scratch.rkt>(map和-l(gentruth 2'(#t#f)))
“(#t#f#f#f)

打捞原始
和-l
程序
请注意,
和-l-bad
不适用于参数列表,而是适用于包装在列表中并传递给过程体的未指定数量的参数:

scratch.rkt>(和-l-bad#t#f#f)
#f
scratch.rkt>(和-l-bad#t#t#t)
#t
scratch.rkt>(和-l-bad#f#f#t)
#f
记住这一点,无需将
和-l-bad
重写为
和-l
即可实现OP目标。相反,重新思考
(应用map和-l(gen truth 2'(#t#f))

scratch.rkt>(map(lambda(x)(apply and-l-bad x))(gen-truth 2'(#t#f)))
“(#t#f#f#f)
这里,
map
将函数应用于
gen truth
返回的列表中的每个布尔列表。该函数接受一个布尔列表,并将
apply
和-l-bad
一起应用于它,例如
(apply和-l-bad'(#t#f)
-->
(和-l-bad#t#f)
,这正是
和-l-bad
所期望的


和进程
过程
和-l-bad
实际上类似于
,因为它接受数量不确定的参数,并返回将参数与
组合的结果:

scratch.rkt>(和-l-bad#t#t#f#t)
#f
scratch.rkt>(和#t#t#f#t)
#f
但是有一个重要的区别:
和-l-bad
是一个过程,而
是一种特殊形式。过程总是计算所有参数,但特殊形式有特殊的计算规则。特殊形式
依次计算其参数,直到结果已知,或者返回第一个
#f
在该序列中遇到,或序列的最后一个值。这是短路评估

和-l-bad
的更好名称可能是
和proc
。原始名称
和-l
建议将
应用于列表(这不是真的),而
和proc
强调这是一个行为类似于
的过程

为什么您首先需要像
和proc
这样的东西?嗯,
apply
为它的第一个参数使用一个过程,所以
(map(lambda(x)(apply和x))(gen truth 2'(#t#f))
将不起作用。但是这将起作用:

scratch.rkt>(映射(lambda(x)(应用和过程x))(gen truth 2'(#t#f)))
“(#t#f#f#f)
这里我们使用了一个类似于
的过程,其中
本身不起作用。
和proc
的缺点是它总是计算所有参数;这并不总是可取的


如何避免编写新的
和类似
的过程

在此处使用
编写一个新的过程来处理,完全可以避免:

scratch.rkt>(映射(lambda(x)(和映射标识x))(gen truth 2'(#t#f)))
“(#t#f#f#f)
这里的
(lambda(x)(andmap identity x))
是一个过程,它接受其参数并将它们与
相结合。也就是说,
((lambda(x)(andmap identity x))”(#t#f))
等价于
(和(identity#t)(identity#f))
。这个过程像以前一样映射到布尔列表上

这相当于本答案顶部定义的
和-l
,而
和-l
实际上可以更好地定义为:

(定义(和-lxs)
(和地图标识xs))

仍然无法识别何时使用apply以及在何处不需要它。如果你有一个函数,比如说3个参数,你可以像这样调用它:
(func x y z)
。但是如果你将这三个参数打包在一个列表中,
”(x y z)会怎么样
,但你想对这三个参数调用同一个函数吗?然后用
apply
(apply func'(x y z))
调用它。这里的答案是:@X10D--答案指出:“请不要。”
(apply map and-l (gen-truth 2 '(#t #f)))