Modern Haskell supports zero-cost coercions, a mechanism where types that share the same run-time representation may be freely converted between. To make sure such conversions are safe and desirable, this feature relies on a mechanism of roles to prohibit invalid coercions. In this work, we show how to incorporate roles into dependent types systems and prove, using the Coq proof assistant, that the resulting system is sound. We have designed this work as a foundation for the addition of dependent types to the Glasgow Haskell Compiler, but we also expect that it will be of use to designers of other dependently-typed languages who might want to adopt Haskell's safe coercions feature. A newtype in Haskell 1 is a user-defined algebraic datatype with exactly one constructor; that constructor takes exactly one argument. Here is an example:
newtype HTML = MkHTML StringThis declaration creates a generative abstraction; the HTML type is new in the sense that it is not equal to any existing type. We call the argument type (String) the representation type. Because a newtype is isomorphic to its representation type, the Haskell compiler uses the same in-memory format for values of these types. Thus, creating a value of a newtype (i.e., calling MkHTML) is free at runtime, as is unpacking it (i.e., using a pattern-match).However, the Haskell type checker treats the newtype and its representation type as wholly distinct, meaning programmers cannot accidentally confuse HTML objects with String objects. We thus call newtypes a zero-cost abstraction: a convenient compile-time distinction with no cost 1 In this paper, we use łHaskellž to refer to the language implemented by the Glasgow Haskell Compiler (GHC), version 8.6.