【问题标题】:The Little Schemer: What is a function or argument's structure?The Little Schemer:什么是函数或参数的结构?
【发布时间】:2015-10-22 12:50:32
【问题描述】:

The Little Schemer的第 3 章中,对于我们为什么不立即简化 rember 函数的问题的答案是“因为函数的结构与其参数的结构不一致。 "我无法理解函数的结构是什么,参数的结构是什么,以及它们之间的区别是什么。

这是未简化的版本:

(define rember
  (lambda (a lat)
    (cond
      ((null? lat) (quote ()))
      (else (cond
        (( eq? (car lat) a) (cdr lat))
        (else (cons (car lat)
          (rember a
            ( cdr lat)))))))))

这是简化的:

(define rember
  (lambda (a lat)
    (cond
      ((null? lat) (quote ()))
      ((eq? (car lat) a) (cdr lat))
      (else (cons (car lat)
               (rember a (cdr lat)))))))

据我所知,主要区别在于该功能已从两个 conds 各问一个问题变为一个 conds 问两个问题。

函数的参数是原子“a”和列表“lat”。

这是第一次,除了密密麻麻的前言之外,本书引用了“结构”这个词。在我看来,到目前为止,“结构”一词的定义是可以解释的。

有人问过这个exact question here before,但我无法回答。为什么两个条件结构与列表的结构一致或不一致?一份清单,在我看来,根本就没有任何条件!

条件不等于Scheme中的问题吗?也许我误解了条件是什么,这可能是我沮丧的合理根源。无论如何,对此的任何澄清将不胜感激!谢谢!

【问题讨论】:

    标签: scheme structure conditional-statements racket the-little-schemer


    【解决方案1】:

    这里对于“函数结构”作者可能是指函数体,即条件:

    (cond
     ((null? lat) ...)
     (else ... (cond... (car lat) ... (cdr lat) ...)))
    

    完全按照列表​​的“递归”定义模式,如下:

    • 一个空列表,或
    • 一个包含至少一个元素(汽车)和一个列表(cdr)的值。

    新定义将两个条件“折叠”在一个条件内,因此函数的“结构”(cond 的结构)不再反映其列表参数的“结构”。

    【讨论】:

    • 谢谢!这对我来说很有意义。那么,在简化定义中,该模式会将列表的所有元素放在一个项目符号中,而不是两个?
    • @s9_C 不,三个 - 根据“简化”cond 代码中的三个案例。
    • 在简化定义中,列表递归定义的第二种情况(car 是一个元素,cdr 是一个列表)由条件的第二个和第三个分支,这样cond 原来的“双向”结构现在是一个“三向”结构,函数不再与列表定义的结构“平行” .有用的参考资料:L. Aiello、G. Attardi 和 G. Prini。走向更具声明性的编程风格。在编程概念的正式描述中。北荷兰,1978 年。 IFIP TC-2 会议,加拿大圣安德鲁斯。
    • 啊,太棒了!这对我来说很有意义。非常感谢 Renzo 和 Will Ness!
    • 我很高兴!
    【解决方案2】:

    List 是一种可以用一些伪代码定义的类型,如

    (define-variant-record list
        ( () )               ; '() is a list
        ((hd . tl)           ; a cons pair (with car field named `hd` and cdr `tl`)
              (list tl)) )   ;  is a list, if `tl` itself is a list
    

    然后,可以使用假设的(参见 EOPL)模式匹配构造 variant-case 来处理它:

    (define rember
      (lambda (a lat)        ; an atom and a list of atoms
        (variant-case (lat)  ; follow the `lat` --
          ( ()               ; an empty list case, or
              (quote ()))
          ( (hd . tl)        ; a non-empty list, with car field `hd` and cdr `tl`
              (cond 
                 (( eq? hd a) tl)
                 (else 
                    (cons hd
                          (rember a tl))))))))
    

    其中,通过使用属于list 的数据类型定义的variant-case,自然而明显地遵循其结构(即其定义的两种情况)。

    第一个公式(带有嵌套的conds)只是模拟不存在的variant-case,并显式访问具体的数据类型实现,cars 和cdrs 作为它做。

    内部的cond不属于这个,只是自己处理rember的细节。这就是为什么将两个conds 混合在一起可能会被视为将不相关的关注点混合到一个混合中的原因(一般来说;虽然这里都非常简单明了)。

    【讨论】:

    • 感谢您的回复!如果您能澄清一点,我将非常感激。当简化版本还包含寻址空列表、带有汽车和 cdr 的列表以及递归的行时,简化版本如何不模拟不存在的变体情况?
    • 第一个版本确实模拟了变体情况,即它确实遵循数据结构(此处为列表)。啊,你说的是第二个。在编辑中解决。只是因为数据类型有两种情况,而不是三种。
    • 感谢您的澄清,Will Ness!您的回答正是我理解问题所需要的。
    猜你喜欢
    • 1970-01-01
    • 2012-09-06
    • 2018-04-12
    • 2022-01-15
    • 2011-06-14
    • 2010-12-15
    • 2012-05-16
    • 1970-01-01
    • 2014-06-28
    相关资源
    最近更新 更多