// $Id: Cons.java,v 1.5 1999/11/05 19:28:33 leavens Exp $

package lib;

/** cons cells, or pairs, as in Lisp */
public class Cons {
    protected Object fst, snd;

    /** construct a Cons object */
    public Cons(Object x, Object y) {
        fst = x;
        snd = y;
    }

    /** an overload of the constructor, convenient */
    public Cons(double x, Object y) {
        fst = new Double(x);
        snd = y;
    }

    /** return the first element of the pair */
    public Object car() { return fst; }

    /** return the second element of the pair */
    public Object cdr() { return snd; }

    // internal iteration
    /** a reflection of Scheme's map procedure */
    public Cons map(Function body) {
        return new Cons(body.value(fst),
                        (snd == null)
                        ? null
                        : ((Cons)snd).map(body));
    }

    /** a reflection of filter in Scheme */
    public Cons filter(BooleanFunction pred) {
        if (pred.value(fst)) {
            return new Cons(fst,
                            (snd == null)
                            ? null
                            : ((Cons)snd).filter(pred));
        } else {
            return
                ((snd == null)
                 ? null
                 : ((Cons)snd).filter(pred));
        }
    }

    /** return a String representation of the pair */
    public String toString() {
        return "(" + fst + " . " + snd + ")";
    }

    /** return a new pair that shares the components of this */
    public Object clone() {
        return new Cons(fst, snd);
    }

}
