A Pizza lényeges újításként a Java típusrendszerét funkcionális típusrendszerrel egészítette ki.
E fejezet elolvasása előtt érdemes elolvasni a 'Sablon' fejezetet.
Pizza-ban lehetőség van castolni primitív típus és dobozoló osztálya között.
Idő közben a fenti példában lévő castolások nagy részét már a Java is támogatja, kivétel amikor egy Object típusú változót castolnánk primitív típusra. A Pizza a fenti kódot az alábbi Java kódra fordítja:
Mindazonáltal ezekkel óvatosan kell bánni, futás idejű hibákat eredményezhetnek.
Algebrai adattípus olyan típus, ami azt határozza meg, hogy a típusba tartozó elemeket hogyan lehet létrehozni. Például:
A fenti példából egy olyan Tree (bináris fa) nevű Java osztály generálódik, melynek lesz egy statikus Tree típusú Empty (üres fa) nevű adattagja, valamint egy Tree -ből származtatott belső statikus osztálya Branch (csúcspont) néven, melynek lesz egy konstruktora a fent látható paraméterezéssel, és a konstruktor paraméterezésében felsorolt formális paraméterek mindegyikéhez készül egy-egy adattag is a Branch osztályba. Amennyiben csak egy case ág van az osztályban, akkor használhatjuk az adott esetre névnek az osztály nevét is, mivel ilyenkor nem generálódik külön belső osztály, hanem az aktuális osztály fog a case-ben megadott paraméterezéssel konstruktort és adattagokat kapni.
A Tree használatára példa:
Az import Tree.*;-re azért volt szükségünk, hogy a Tree.Branch és Tree.Empty helyett simán írhassunk Branch-et és Empty-t. Ezt algebrai típusok nélkül is meg lehetne csinálni. Készítenénk egy absztrakt bázisosztályt (Tree), és származtatnánk két másik osztályt, ami reprezentálja az algebrai típus eseteit (EmptyTree, Branch). A Tree típusú paramétert váró metódusokban pedig az instanceof operátort és sok-sok típuskényszerítést alkalmaznánk.
A Pizza készítésekor a Java még nem rendelkezett felsorolási (enum) típussal. Felsorolási típus hiányában megoldható az adott probléma konstans egészek használatával is, de ennél jobb megoldást jelent a Pizza algebrai típusa. Olvasható kódot ad, valamint nagy előnye a konstans egészekkel szemben, hogy ekkor fordítási idejű típusellenőrzést kapunk a felsorolásban szereplő elemekre, így nem használhatunk definiálatlan értéket. Egy példa ennek használatára:
Figyeljük meg, hogy ebben az esetben a Java 5-ben bevezetett felsorolási típushoz hasonlóan elég egyszerűen készíthetnénk akár konstruktort és adattagokat a felsorolás elemei számára. A Pizza fordító ezt a kódot olyan Java kódra fordítja, ahol a felsorolás elemei a tartalmazó osztály típusával megegyező típusú adattagok lesznek.
Újdonság a Java-hoz képest, hogy megjelent a függvény típus, így alprogramokat tudunk tárolni objektumokban (olyan, mint C++-ban a függvényre mutató pointer). Természetesen a függvények paraméterei és visszatérési értéke lehetnek függvénytípusúak is. Az ilyen függvényeket hívjuk magasabbrendű függvényeknek. Azokat a függvényeket, amelyeknek nincs függvénytípusú paramétere vagy visszatérési érteke azokat elsőrendű függvénynek hívjuk. A szintaxis a következő:
Ha a függvény kivételeket is dob:
A Java szintaktikai tradícióját követve azt várhattuk volna, hogy a resulttype(argtype1, ..., argtypen) jelölést használják a függvénytípushoz. Szerencsére a Pizza tervezői más utat választottak. Két okból is:
Deklarálhatunk függvénytípusú változókat, pl:
Így kapunk egy (int, String) -> char típusú CharAt nevű változót. Ennek értékül adhatunk azonos szignatúrájú függvényeket. Itt a szignatúrába beletartozik a visszatérési érték típusa is. A függvénytípust például akkor tudjuk használni, amikor egy osztály nem implementált egy interfészt. Ahelyett, hogy egy wrappert írnánk (mint a későbbiekben látni fogjuk), a kért függvényt paraméterként adjuk át a metódusnak. Például nézzük a String Java osztály compareTo() metódusát. Ez lexikografikusan és kis-nagybetűt megkülönböztetve hasonlít össze két String-et. Tegyük fel, hogy String-eket akarunk rendezni. Ha meg akarjuk változtatni a rendezés viselkedését, akkor átadunk paraméterként egy függvényt, ami String-eket hasonlít össze: