美文网首页
Lisp 中 /^c[ad]+r$/ 的 Ruby 实现

Lisp 中 /^c[ad]+r$/ 的 Ruby 实现

作者: Troubleshooting | 来源:发表于2016-03-12 14:33 被阅读35次

    我先简单说明一下我到底是想分享什么东西,对于没接触过 Lisp 的小伙伴很有必要,我只针对 carcdr 这两种序列操作简单说明一下,有兴趣的小伙伴去看 SICP,难免我讲的太片面

    car z 取数组 z 中第一个元素, 就相当 z.first,这个没有什么特殊情况就这样理解就好
    cdr z 取 z 中余下的元素,z.last 或 z[1 .. -1]
    想要的效果是像下面这样:
    cdar z 是这样 z[1 .. -1].first 也就是 z[1] 但也不见得是 z[1]
    cddr z 就取两次剩余,相当与 z[1 .. -1][1 .. -1] 也就是 z[2 .. -1]
    cadadadadaddadadadadadr, ......
    caaaaaaaaaaaaaaar, ......
    cdddddddddddaaaaaaaaaaaaar, ......
    

    上述只是简单用 Ruby 数组表示序列和序对,有些事情没说的不是很清楚,再用 C 代码简单描述一下序对大概会长什么样子,因为源码我也没看过,下面只是我的理解,希望也能帮助你加深理解:

    # 序对可以被定义成这样,其中 x, y 可指向任意类型
    typedef struct {
        void *x;
        void *y;
    } pair;
    
    # 所谓序列,就是由上述序对构成的一个单向链表
    

    我还是用 Ruby 吧不影响什么的,下面几个简单方法写出来帮助小伙伴再次理清思路

      def list *args; args; end
    
      def cons x, y; list x, y; end
    
      def pair? z; z.length == 2; end
    
      def car z; z.first; end
    
      def cdr z; pair?(z) ? z.last : z[1 .. -1]; end
    

    最后,因为涉及函数式语言,应避用免循环实现,需要用是一个递归的 method_messing 实现 cadr, cdadr, caddaddr, ... 等诸如此类

      def method_missing method, *args
        return super unless method =~ /^c[ad]+r$/ and method.length > 3
        send "c#{method[2..-2]}r", send("c#{method[1]}r", *args)
      end
    

    相关文章

      网友评论

          本文标题:Lisp 中 /^c[ad]+r$/ 的 Ruby 实现

          本文链接:https://www.haomeiwen.com/subject/lryxlttx.html