Display of ADTs


Typically, an end-user of Pivotal will work in terms of visual representations of the abstract values of interest in his/her particular domain of interest. The implementation of these abstract values and the definition of their visual representation will be programmed by a Pivotal tool builder, assumed to be an expert functional programmer.

The 'Display' class

In a traditional, interactive text-based Haskell environment, such as Hugs or GHCi, when an expression is typed at the prompt, it is converted into a string and shown on the output device. The conversion into a string takes place by the implicit application of the show method of the Show class:
class Show a where
    show :: a -> String                           
    . . .
In Pivotal, in an analogous way, when an expression occurs in a document, it is converted into a picture and displayed at that point in the document. The conversion into a picture takes place by the implicit application of the display method of the Display class:
class Show a => Display a where
    display :: a -> Pic                           
    . . . 
    display x = PicText black 12 (show x)   -- default method for 'display'
For user-defined types, the implementor is free to define an appropriate instance declarations of the Show and Display classes. For example, for an ADT representing positions in the game of chess, the display method could be defined to display positions in the conventional diagrammatic form.

If, for a particular type, the display method is not explicitly defined, the default method of the class is used. This (see above) uses the show method to convert the value into a string and then the PicText constructor to convert this string into a 'picture' of the string. Since no 'display' declarations are made for the standard types (Bool, Int, etc.) defined in the Prelude, values of these types are thus displayed in textual form in the usual way.

Example

As a (rather simple!) example, suppose an end-user has an interest in triangles. A first step would thus be for the user (or a tool-builder) to introduce a representation for triangles. This could be simple datatype with a constructor for holding the lengths of the three sides of the triangle:
data Triangle = Tri Double Double Double  deriving Show
With this type defined, the user is able to construct value of type Triangle and display their values textually. For example: However, in this context, a textual representation is not a very intuitive form to use.

Defining a pictorial representation

Suppose the user would prefer to be able to display values of type Triangle pictorially. This is easily done: a conversion function, of type:
drawTri :: Triangle -> Pic
drawTri (Tri a b c) = Poly red False [ . . . ]
can be written to compute the coordinates of the vertices as a function of the lengths of the sides and used to display triangle values:

Defining an instance of the Display class

Finally, we can define an instance, for the type Triangle, for the Display class. This means that the system will then automatically invoke the drawTri function whenever a value of type Triangle needs to be displayed. For example: