代码之家  ›  专栏  ›  技术社区  ›  Jason Baker

什么是scheme等价于tuple解包?

  •  17
  • Jason Baker  · 技术社区  · 14 年前

    在Python中,我可以这样做:

    t = (1, 2)
    a, b = t
    

    ……a是1,b是2。假设我有一张单子 '(1 2) 在计划中。有没有办法做类似的事情 let ? 如果有区别的话,我就用球拍。

    6 回复  |  直到 14 年前
        1
  •  26
  •   Eli Barzilay    14 年前

    在球拍中你可以使用 match ,

    (define t (list 1 2))
    (match [(list a b) (+ a b)])
    

    以及相关的事情,比如 match-define :

    (match-define (list a b) (list 1 2))
    

    match-let

    (match-let ([(list a b) t]) (+ a b))
    

    它适用于列表、向量、结构等。对于多个值,您可以使用 define-values :

    (define (t) (values 1 2))
    (define-values (a b) (t))
    

    let-values . 但请注意,我无法定义 t 作为“元组”,因为在(大多数)方案实现中,多个值不是第一类值。

        2
  •  8
  •   Watcom    12 年前

    赤裸裸的成语是 应用 具有 兰姆达 你会用到的地方 ,例如:

    (define t '(1 2))
    (apply (lambda (a b)
              ;; code that would go inside let
            )
            t)
    

    其优点是它可以在任何实现上工作。当然,这只能用于简单的情况,但有时这就是你所需要的。

        3
  •  7
  •   Chris    14 年前

    你要找的东西(至少在Lisp世界里)的通用术语是 解构 实现它的宏称为 解构绑定 . 在Common Lisp中,它的工作方式如下:

    (destructuring-bind (a b c) '(1 2 3)
      (list a b c)) ;; (1 2 3)
    

    它也适用于多个“级别”的嵌套:

    (destructuring-bind (a (b c) d) '(1 (2 3) 4)
      (list a b c d)) ;; (1 2 3 4)
    

    好像有一个 nice implementation 将bind作为scheme宏进行解构。

        4
  •  4
  •   icyrock.com    14 年前

    我想这就是你要找的:

    看看 let-values let+ .

        5
  •  0
  •   Jason Stewart    6 年前

    如果你不想把 match 附属国:

    从列表中:

    (let-values ([(a b c) (apply values '(1 2 3))])
      (+ a b c))
    

    或者直接从值表达式:

    (let-values ([(a b c) (values 1 2 3)])
      (+ a b c))
    
        6
  •  0
  •   Syzygies    6 年前

    这里有一个简单的 destructuring-bind 方案的宏 case-lambda (如球拍或Chez计划):

    (define-syntax bind
       (syntax-rules ()
          ((_ arg pat def body)
             (apply
                (case-lambda
                   [pat body]
                   [x def] )
                arg ))))
    

    下面是激发我编写此宏的示例。将默认值放在主体之前可以使代码可读:

    (define (permutations l)
       ;
       (define (psub j k y)
          ;
          (define (join a b)
             (bind a (ah . at) b
                (join at (cons ah b)) ))
          ;
          (define (prec a b z)
             (bind b (bh . bt) z
                (prec (cons bh a) bt
                   (psub (cons bh j) (join a bt) z) )))
          ;
          (if (null? k)
             (cons (reverse j) y)
             (prec (list) k y) ))
       ;
       (psub (list) (reverse l) (list)) )
    

    以下是计算不同方案中长度为9的排列的基准:

    0m0.211s Chez Scheme
    0m0.273s Bigloo
    0m0.403s Chicken
    0m0.598s Racket
    

    转换为GHC Haskell比Chez方案快5倍。诡计比这些计划都慢得多。

    除了利用现有的便利性之外 朗姆达案 代码,我喜欢这个宏如何接受与函数定义参数列表完全相同的语法。我喜欢简单的计划。我已经足够大了,可以记住在穿孔卡片上编程Fortran,在穿孔卡片上,允许的语法随上下文的变化而变化很大。这个计划应该比那个更好。在这样的宏上引导百合花的冲动是压倒性的。如果您也不能证明更改函数定义的语法是正确的,那么也不要在这里更改语法。有一个正交语法是很重要的。