Apologies to the people  who are only in here to  catch epigram code in
their inbox.
But the partial monad ist discussed  as a device for structuring partial
programming in epigram.
And since I wrote these programs mainly to  get a grip on - a very short
prefix of - the discussion Bas Spitters  and Thorsten had on this list a
while ago, I drop them here.

> {-# OPTIONS -fglasgow-exts #-}

General recursion  augments every data  type with an extra  element, the
divergent compution.

>-- data Empty ; bot = bot :: Empty

Thorsten  and  others  have  suggested  to make  this  manifest  in  the
signature of a program, capturing partiality with the delay monad

> data{- codata -}  D a = Now a | Later (D a) ; never = Later never
 
> instance Monad D where
>         return        = Now
>         Now a   >>= f = f a
>         Later d >>= f = Later (d >>= f)

which allows for a notion of a 'race'

> (%) :: D a -> D a -> D a
  
> Now a     % _         = Now a
> _         % Now a     = Now a
> Later d   % Later e   = Later (d % e)
 
('synchronisation' is also at hand)

> (&) :: D a -> D a -> D a
 
> Now a     & Now _     = Now a
> a@(Now _) & Later d   = Later (a & d)
> Later d   & a@(Now _) = Later (d & a)
> Later d   & Later e   = Later (d & e)

The delay  monad explains for example  why the /trivial/ fixed  point of
monadic computations isn't very useful.

>-- class Monad m => MonadFix m where
>--         mfix :: (a -> m a) -> m a

>-- instance MonadFix D where
>--         mfix f = f =<< (mfix f)
 
Because taking

> bot = never

this mfix computes  the /least fixed point/ of a  partial program lifted
to a partial domain. Which clearly is bot.

---------------------------------------------------------------------------

Topologists with a heart for computability theory are fond of this datatype

>-- data S = T ; bot = bot :: S

which allows the type of /definable characteristic functions/ of subsets
to be defined as this

>-- type Open a = a -> S

and things start to get interesting with programs of type Open S.

But to be able to define the union of subsets

>-- u `union` v = \x -> u x `or` v x

one needs the following equations to hold.

>-- T   `or` T   = T
>-- T   `or` bot = T
>-- bot `or` T   = T
>-- bot `or` bot = bot

Enter the delay monad...

Quotienting with respect to termination

> top = {- Later $ ... Later $ -} Now never

makes  at  least  the  important  ones from  the  above  equations  hold
/definitionally/.

>-- top % bot ~~> top
>-- bot % top ~~> top

And we can head for a 'subobject classifier'.

> data Zero               {- -}
> type One = D Zero       {- bot -}
> type Omega = D One      {- bot,top -} ; top :: Omega

Now, before you go "Boring!" just because of this

> type Sub a = a -> Omega

> empty :: Sub a   
> empty = const bot

> whole :: Sub a
> whole = const top

consider again the topology of the Sierpinski space.

> [{- -}_,{-top-}_,{-bot,top-}_] = [empty,id,whole] :: [Sub Omega]

Why is {-bot-} :: Sub Omega  missing?

Union and intersection are now definable

> (\/),(/\) :: Sub a -> Sub a -> Sub a

> u \/ v = \a -> u a % v a
> u /\ v = \a -> u a & v a

and readily extend to the countable and finite cases respectively.

> (\/.), (/\.) :: [Sub a] -> Sub a

> (\/.) = foldr (\u v -> u \/ (Later . v)) empty

> (/\.) = foldr (/\) whole

Please note that

> locale :: Sub a -> [Sub a] -> Sub a
> locale =  \   u -> \us     -> u /\ (us \/.)

is well defined even if us is /countable/.

And we can have a poor man's roll your own TT:

> subzero :: Zero -> a
> subzero = \_    -> error ['0'..]

>-- (%),(&) :: Omega -> Omega -> Omega

> type Prop = Sub One

> false :: Prop
> false = \i -> case i of
>                 Now x   -> subzero x
>                 Later d -> Later (false d)

> true :: Prop
> true = Now            -- see subject line


Alladat must  have to with 'coalgebras  give rise to toposes'.  But that
requires more hunting & gathering at the library on my part.


Best regards,
Sebastian

Reply via email to