▁ancest or ▁are ▁permitted ▁on ▁the ▁union ▁type , ▁but ▁they ▁may ▁also ▁have ▁other ▁valid ▁operations ▁in ▁common ). ▁ ▁Ex ist ential ▁types ▁▁ ▁Ex ist ential ▁types ▁are ▁frequently ▁used ▁in ▁connection ▁with ▁record ▁types ▁to ▁represent ▁modules ▁and ▁abstract ▁data ▁types , ▁due ▁to ▁their ▁ability ▁to ▁separate ▁implementation ▁from ▁interface . ▁For ▁example , ▁the ▁type ▁" T ▁= ▁ ∃ X ▁{ ▁a : ▁X ; ▁f : ▁( X ▁→ ▁int ); ▁} " ▁describes ▁a ▁module ▁interface ▁that ▁has ▁a ▁data ▁member ▁named ▁a ▁of ▁type ▁X ▁and ▁a ▁function ▁named ▁f ▁that ▁takes ▁a ▁parameter ▁of ▁the ▁same ▁type ▁X ▁and ▁returns ▁an ▁integer . ▁This ▁could ▁be ▁implemented ▁in ▁different ▁ways ; ▁for ▁example : ▁▁ ▁int T ▁= ▁{ ▁a : ▁int ; ▁f : ▁( int ▁→ ▁int ); ▁} ▁ ▁float T ▁= ▁{ ▁a : ▁float ; ▁f : ▁( float ▁→ ▁int ); ▁} ▁ ▁These ▁types ▁are ▁both ▁sub types ▁of ▁the ▁more ▁general ▁exist ential ▁type ▁T ▁and ▁correspond ▁to ▁concrete ▁implementation ▁types , ▁so ▁any ▁value ▁of ▁one ▁of ▁these ▁types ▁is ▁a ▁value ▁of ▁type ▁T . ▁Given ▁a ▁value ▁" t " ▁of ▁type ▁" T ", ▁we ▁know ▁that ▁" t . f ( t . a )" ▁is ▁well - ty ped , ▁regardless ▁of ▁what ▁the ▁abstract ▁type ▁X ▁is . ▁This ▁gives ▁flex ibility ▁for ▁choosing ▁types ▁su ited ▁to ▁a ▁particular ▁implementation ▁while ▁clients ▁that ▁use ▁only ▁values