Are there ruby equivalents to car, cdr, and cons?

前端 未结 5 939
终归单人心
终归单人心 2021-02-05 05:35

Are there ruby equivalents to the lisp car, cdr, and cons functions? For those unfamiliar with lisp, here\'s what I want from ruby:

[1,2,3].car   => 1
[1,2,3]         


        
5条回答
  •  醉酒成梦
    2021-02-05 06:24

    This is how you'd implement lisp-like single-linked lists in ruby:

    class Object
      def list?
        false
      end
    end
    
    class LispNilClass
      include Enumerable
      def each
      end
    
      def inspect
        "lnil"
      end
    
      def cons(car)
        Cell.new(car, self)
      end
    
      def list?
        true
      end
    end
    
    LispNil = LispNilClass.new
    
    class LispNilClass
      private :initialize
    end
    
    class Cell
      include Enumerable
    
      attr_accessor :car, :cdr
    
      def initialize(car, cdr)
        @car = car
        @cdr = cdr
      end
    
      def self.list(*elements)
        if elements.empty?
          LispNil
        else
          first, *rest = elements
          Cell.new(first, list(*rest))
        end
      end
    
      def cons(new_car)
        Cell.new(new_car, self)
      end
    
      def list?
        cdr.list?
      end
    
      # Do not use this (or any Enumerable methods) on Cells that aren't lists
      def each
        yield car
        cdr.each {|e| yield e}
      end
    
      def inspect
        if list?
          "(#{ to_a.join(", ") })"
        else
          "(#{car} . #{cdr})"
        end
      end
    end
    
    list = Cell.list(1, 2, 3) #=> (1, 2, 3)
    list.list? #=> true
    list.car #=> 1
    list.cdr #=> (2, 3)
    list.cdr.cdr.cdr #=> lnil
    list.cons(4) #=> (4, 1, 2, 3)
    
    notlist = Cell.new(1,2) #=> (1 . 2)
    notlist.list? #=> false
    notlist.car #=> 1
    notlist.cdr #=> 2
    notlist.cons(3) #=> (3 . (1 . 2))
    

提交回复
热议问题