package haskell.example;

import haskell.lang.Data;
import haskell.lang.Exp;
import haskell.prelude.AbstractShow;
import haskell.prelude.Int;
import haskell.prelude.String;
import haskell.prelude.text.Show;

/**
 * data Person = Persson { name :: String, age :: Int }
 *     deriving Show
 */
public class Person
        extends AbstractShow<Person>
        implements Data<Person>,
                Show<Person> {

    public final String name;
    public final Int age;

    public Person(final String name, final Int age) {
        this.name = name;
        this.age = age;
    }

    public Person(final Exp<Person> expression) {
        super(expression);
        this.name = null;
        this.age = null;
    }

    public static String name(final Person x) {
        return x.eval().name;
    }

    public static Int age(final Person x) {
        return x.eval().age;
    }

    public static Person setName(final String newName, final Person x) {
        return new Person(newName, age(x));
    }

    public static Person setAge(final Int newAge, final Person x) {
        return new Person(name(x), newAge);
    }

}
