【问题标题】:or as procedure in scheme或作为方案中的程序
【发布时间】:2018-06-01 07:27:26
【问题描述】:

我想将or 应用于列表的每个元素,例如: (apply or '(#t #t #f)) 预期结果 #t,但我收到错误:

'#' to 'apply' 类型错误(kawa.lang.Macro)(预期:过程、序列或其他运算符)

据我了解,or 不是程序。 有什么程序可以代替or吗?

【问题讨论】:

  • 你可以定义你自己的使用or的过程。
  • 如何从'(#t #t #f) 的“应用或应用于每个元素”到#t 的结果?
  • (or #t #t #f)true or true or false 相同,是真的
  • 正如@ScottHunter 所说,我确实编写了自己的程序并且它有效,(define (orp . ls) (if (< (length ls) 2) (car ls) (or (car ls) (orp (cdr ls)))))

标签: functional-programming macros scheme apply variadic-functions


【解决方案1】:

您可以定义自己的过程,使用或

(define (orp . ls) 
     (if (null? ls) #f
           (if (< (length ls) 2) (car ls) (or (car ls) (orp (cdr ls))))))

并使用它:

(apply orp '(#t #f #t))

【讨论】:

  • &gt; (orp) . . car: contract violation expected: pair? given: '()
  • 你能告诉我如何在某些情况下使用它吗?我看不懂这段代码。
  • 不带参数运行它:(or) 产生#f,而(orp) 抛出错误。
【解决方案2】:

最简单的方法是使用exists*。无论何时使用(apply or some-list),都可以使用(exists values some-list)。或者,如果您愿意,您可以定义一个使用 exists 的函数来执行此操作:

#!r6rs
(import (rnrs base)
        (rnrs lists))

(define (or* . lst)
  (exists values lst))

values 是恒等函数,所以(values x) 就是x

exists 是一个高阶函数,因此(exists f (list x ...)) 等价于(or (f x) ...)

例如(exists values (list #t #t #f))等价于(or (values #t) (values #t) (values #f)),与(or #t #t #f)相同。

试一试:

> (apply or* '(#t #t #f))
#t
> (apply or* '(#f #f #f))
#f
> (or* #t #t #f)
#t
> (or*)
#f

*exists 有时称为ormapany

【讨论】:

  • 这是特定于球拍的,但问题未标记
  • 您能解释一下您的方法吗,我无法阅读代码,并且在尝试执行时收到警告。
  • 方案没有ormap
  • 是叫any 还是exists 还是什么?
  • 您能否编辑您的代码以使其完全正常工作,以便我接受您的回答?
【解决方案3】:

重点是or(和ifcondand ....)运算符具有lazy evaluation 语义。因此(or #t (/ 1 0)) 不会除以零。因为or不能是一个普通的函数。

您可以编写一个 lambda 代码来强制进行急切评估,例如定义您的 eager-or 可变参数函数,然后应用它。

【讨论】:

    【解决方案4】:

    SRFI-1 List Library 中,您有everyany,基本上是andor,用于列表上的过程。

    #!r6rs
    
    (import (rnrs base)
            (only (srfi :1) every any)
    
    (define num1-10 '(1 2 3 4 5 6 7 8 9 10))
    (define odd1-9 '(1 3 5 7 9))
    
    (every odd? num1-10) ; ==> #f
    (any odd? num1-10)   ; ==> #t
    (every odd? odd1-9)  ; ==> #t
    

    对于布尔值列表,过程只需要返回参数。 values 返回它的参数并作为身份:

    (define booleans '(#f #t))
    (every values booleans) ; ==> #f
    (any values booleans)   ; ==> #t
    

    SRFI-1 是一个安全的选择,因为它是即将推出的 R7RS Red 版本的列表库。在许多 R5RS 和 R6RS 实现中都包含 SRFI-1,如果没有,您可以轻松地从 SRFI 参考实现中添加它。在 DrRacket 的默认语言 DrRacket 中,有 ormapandmap,您可以选择使用 SRFI-1,而不是使用 (require srfi/1) 导入它们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-19
      • 2019-12-10
      • 2017-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-06
      相关资源
      最近更新 更多