Existential types, object-orientation.

Marco Pil marcop@cs.kun.nl
Fri, 7 Nov 1997 13:45:03 +0100


Dear Nick,

>>> Can one can use inheritence or class polymorphism with Existential
>>> types in Clean? If not, are these concepts even compatible?

No, you cannot use inheritence with Existential types in Clean.
I do not know whether they are fundamentally incompatible. On first
glance this does not seem to be the case however.


> Can you give a simple example of a dynamic type in clean and a spiffy
> function that uses it to do something otherwise impossible?

Dynamic types are about to be implemented in Clean. Two constructs have
been defined.
One for packing a value together with its type:
   dynamic 5 :: Int

And one for unpacking the 'dynamic' object again, by doing a run-time
pattern match on its type:
   f :: Dynamic -> Int
   f (x :: Int)  = x
   f (x :: Bool) = if x 1 0
   f  _          = 0


The spiffy function I would like to show is is a very small command-based,
file-based operating system, somewhat like the Unix Operating System.
It assumes that a file consist of one object of type dynamic, and it
is capable of applying the contents of one file (the command) to the
contents of another (the argument), and check in a run-time type check
that this application is type safe.


Marco Pil

==============================
 Marco Pil
 email:marcop@cs.kun.nl
 http://www.cs.kun.nl/~marcop
 tel: +31 (0) 24 36 52509
==============================



---------------------8<-------------------------8<-----------------------

module OpSys

import StdEnv

/*
    This is a command-based, file-based operating system, somewhat like the
    Unix Operating System.
    The program reads a number of filenames, interpretes the first file as a
    command, and the next files as its arguments.
    Think of the command and its arguments as being a compiler applied to a
    textfile, a previewer applied to a postscript file, or even a new Kernel,
    replacing this one.
*/

Kernel :: *World -> *World
Kernel world
    # (line,world) = getCommandline world
      world = interprete (parse line) world
    = Kernel world
where

    interprete :: [String] *World -> *World
    interprete [] world
        = world
    interprete [command:args] world
        # (commandFile,world) = readDynamic command world
        = addArguments commandFile args world
    where

        addArguments :: Dynamic [String] *World -> *World
        addArguments (command :: *World -> *World) [] world
            = command world
        addArguments (command :: a -> b) [arg:args] world
            # (argFile,world) = readDynamic arg world
            = case argFile of
                (arg :: a) = addArguments (dynamic (command arg) :: b) args
world
                else       = Error "argument has wrong type" world
        addArguments _ args world
            = Error "No such command / command has too many arguments" world


getCommandline :: *World -> (String,*World)
parse :: String -> [String]
readDynamic :: String *World -> (Dynamic,*World)
Error :: String *World -> *World