Head Lazy, but Shapely, and Deeply Mutable. Ben Lippmeier University of New South Wales Type classes are a fabulously useful idea. Although the original motivation for adding them to Haskell was to support operator overloading, on a conceptual level their utility is more general. Type classes define sets of types, usually with some common property. For example, Eq is the set of types that support equality, and Show is the set of types that can be converted to some textual representation. These classes work on types of kind *, that is, the types of values. However, in the Disciple language we also have region, effect and closure types, and we use type classes to reason about these as well. For example, we use HeadLazy for value types who's outermost constructor is in a region that might contain thunks, and Distinct to track regions that are known not to alias. Disciple also supports the destructive update of arbitrary data, and interesting problems arise when we try to define polymorphic update operators that work on data types containing functions. A type like (Int -> Int) has an Int in it, yet that Int cannot be updated. It turns out we need to track which type variables are in "phantom" positions in the data definition, but the obvious approach blows up when applied to nested types. In this talk I'll tell you all about it.