【问题标题】:Scheme default valued function方案默认值函数
【发布时间】:2012-11-19 17:32:50
【问题描述】:

几天来,我一直在为我的计划中的一个想法而苦苦挣扎。我经常以

的风格编写代码
(define fib_h (lambda (n a b) <body ...>))
(define fib (lambda (n) (fib_h n 0 1)))

而且我认为这是向宏介绍自己的好方法。不幸的是,关于如何将其宏化,这似乎有点超出我的理解。我想我在某一时刻接近了

(define-syntax dvf
  (syntax-rules ()
    ((_ f (args ...) (name value) ... body)
      <stuff that didn't work>)))

这将定义一个函数“f”,该函数将采用“args ...”或“args ... name ...”,然后,如果它仅采用“args ...”,则应用“value”。 .." 到 "name ..." 参数。 我可以想到两种好方法来做到这一点。第一个需要 Y 组合器,我真的不想使用它们。另一种方式需要我以某种方式获取“name ...”和“args ...”中的变量数量如果有人可以帮助我解决这个问题,我将不胜感激。

【问题讨论】:

    标签: recursion lisp scheme default tail


    【解决方案1】:

    您可能正在寻找case-lambda 语法,它在SRFI-16 中进行了描述。这是那里给出的实现:

    (define-syntax case-lambda
      (syntax-rules ()
        ((case-lambda)
         (lambda args
           (error "CASE-LAMBDA without any clauses.")))
        ((case-lambda 
          (?a1 ?e1 ...) 
          ?clause1 ...)
         (lambda args
           (let ((l (length args)))
             (case-lambda "CLAUSE" args l 
               (?a1 ?e1 ...)
               ?clause1 ...))))
        ((case-lambda "CLAUSE" ?args ?l 
          ((?a1 ...) ?e1 ...) 
          ?clause1 ...)
         (if (= ?l (length '(?a1 ...)))
             (apply (lambda (?a1 ...) ?e1 ...) ?args)
             (case-lambda "CLAUSE" ?args ?l 
               ?clause1 ...)))
        ((case-lambda "CLAUSE" ?args ?l
          ((?a1 . ?ar) ?e1 ...) 
          ?clause1 ...)
         (case-lambda "IMPROPER" ?args ?l 1 (?a1 . ?ar) (?ar ?e1 ...) 
           ?clause1 ...))
        ((case-lambda "CLAUSE" ?args ?l 
          (?a1 ?e1 ...)
          ?clause1 ...)
         (let ((?a1 ?args))
           ?e1 ...))
        ((case-lambda "CLAUSE" ?args ?l)
         (error "Wrong number of arguments to CASE-LAMBDA."))
        ((case-lambda "IMPROPER" ?args ?l ?k ?al ((?a1 . ?ar) ?e1 ...)
          ?clause1 ...)
         (case-lambda "IMPROPER" ?args ?l (+ ?k 1) ?al (?ar ?e1 ...) 
          ?clause1 ...))
        ((case-lambda "IMPROPER" ?args ?l ?k ?al (?ar ?e1 ...) 
          ?clause1 ...)
         (if (>= ?l ?k)
             (apply (lambda ?al ?e1 ...) ?args)
             (case-lambda "CLAUSE" ?args ?l 
               ?clause1 ...)))))
    

    【讨论】:

    • 补充一点:case-lambda 旨在在R7RS 内实现标准化。
    【解决方案2】:

    我可能没有抓住重点,但这与 Scheme 内置默认参数的工作方式不完全一样:

    (define f1
      (lambda (n (a 0) (b 1))
        (printf "n:~a  b:~a  b:~a\n" n a b)))
    
    (f1 10)
    (f1 10 0 1)
    (f1 10 8 3)
    

    产量

    n:10  b:0  b:1
    n:10  b:0  b:1
    n:10  b:8  b:3
    

    【讨论】:

    • 标准方案没有内置默认参数的任何语法。
    • 方案中没有默认值,使用默认语法。
    • 根据 RnRS,您是对的,对不起。但我实际上从未使用过缺少默认值的 Scheme 实现。
    猜你喜欢
    • 1970-01-01
    • 2016-08-23
    • 1970-01-01
    • 2011-11-20
    • 1970-01-01
    • 1970-01-01
    • 2015-03-15
    • 2019-05-08
    • 1970-01-01
    相关资源
    最近更新 更多