在 Ruby 中创建 `list?` 方法

问题描述 投票:0回答:1

我正在开发一个模仿各种 Racket 功能的 Ruby 程序。目前,我希望实现一个

list?
功能;但是,如果第二个值是一对,我不知道该怎么办(例如,如果我调用
b = cons(1, cons(2, cons(3, Pair.null)))
方法,
list?
应该返回 true)。我目前有以下代码:

#Pair (class): Takes two values and creates a list from them. Executing the code should return a list without displaying any output.
#   Returns: A list of at least two elements.
#   Parameters:
#       value1 (any class, including pair) - a value to insert into list.
#       value2 (any class, including pair) - another value to insert into list.
#
#Declare class `Pair`
class Pair
    #Initialize
    def initialize(value1, value2)
        @value1 = value1
        @value2 = value2
    end

    #Method: car - return the car of the pair.
    def car
        return @value1
    end
    
    #Method: cdr - return the cdr of the pair.
    def cdr
        return @value2
    end
    
    #Method: to_s - Return string representation of the pair.
    # def to_s
    #     "(#{@value1} . #{@value2})" 
    # end

    #Method: list? - returns true if pair is a valid list and false otherwise.
    def list?
        #What do you do if value2 is a pair?
        
        #If value2 is a null (nil) value, then it is a list.
        if (@value2 == nil)
            true
        else
            false
        end
    end

    #Method: count - If the pair is a list, return the number of items in the top level of the list. Return false otherwise.

    #Method: append(other) - If the pair is a list, append should return a new list consisting of `other`` appended to the original list. 

    #Method: null? -  returns true only if the pair is an empty list.

    #Implement a null/empty list value.
    def self.null
        nil
    end

end

#Implement a `pair?` method.
def pair?(p)
    p.is_a?(Pair)
end

#Create a global method `cons`
def cons(val1, val2)
    Pair.new(val1, val2)
end

请尽快回复并提供提示。

ruby
1个回答
0
投票

A list 是递归定义的:它要么是常量

null
,要么是第二个值是列表的对。

https://docs.racket-lang.org/reference/pairs.html#(part._pairs)

由于是递归方法,所以必须不断调用同一个方法:

class Pair
  def initialize(first, second)
    @first = first
    @second = second
  end

  attr_reader :first, :second

  def list?
    return true if second.nil?

    second.is_a?(Pair) ? second.list? : false
  end
end

def cons first, second
  Pair.new(first, second)
end

p cons(1, 2).list?                      #=> false
p cons(1, nil).list?                    #=> true
p cons(1, cons(2, cons(3, nil))).list?  #=> true
© www.soinside.com 2019 - 2024. All rights reserved.