Hi,

it used to be a big problem in functional programming languages (FP)
to handle with input, output and state. Irrefutable patterns, unique
types, continuation passing style and IO monad programming solves this
problem.

In Haskell the IO monad has won the competition between these
solutions. But these leads to another problem:

Every function, that does any IO, has a result type of `IO a',
regardless of the data it actually needs from the state.
E.g. a random-list generating function, that needs only the time for
initialisation of the (internal) seed needs `IO [Int]' as result type,
while a function, that deletes a file needs `IO ()' as result type.

So weather the Programmer nor the Compiler knows which data is
modified by such a function. Because of this, it may be quite
difficult to optimise/parallelise any sequence of functions of the IO
monad.

This particular problem is avoided in Clean by using the uniqness type
attribute. By (de)composing `World', the (hidden) state of the world,
into sub-worlds like `FileSystem', `Events' and sub-sub worlds like
`InFile', `Devices' it is clear which part of the outside, persistent
world is modified by a function. 

It is the questions, if such a decomposition of the hidden state of
the world is possible in Haskell. I think of something like:

main :: ST World ()
getFileSystem :: ST World FileSystem
joinFileSystem :: ST FileSystem a -> ST World a

writeCh :: Char -> ST File ()
readCh :: ST File Char

or

main :: World ()
getFileSystem :: World (FileSystem ())
joinFileSystem :: FileSystem a -> World a

writeCh :: Char -> File ()
readCh :: File Char

If a sophisticated decompositions of the world are chosen, it should
be easier to optimise functions locally and globally and to exploit
the parallelism of interactive function. But this proposal may need
the annotation of uniqness. 

Another possibility is something like this:

main :: ST World ()
runFileSystem :: ST FileSystem a -> ST World a   -- or syncFileSystem
runFile :: ST File a -> ST FileSystem a          --    syncFile

writeCh :: Char -> ST File ()
readCh :: ST File Char

main = do
        runFileSystem  $ do { ... }              -- implicit parallelism
        runEventSystem $ do { ... } 
        ...
        return ()

or

main :: World ()
runFileSystem :: FileSystem () -> World ()
runFile :: File () -> FileSystem ()

writeCh :: Char -> File ()
readCh :: File Char


Regards,
Stefan



Reply via email to