[clean-list] Uniqueness issues for Clean newbie.

Ben Lippmeier Ben.Lippmeier@anu.edu.au
Wed, 30 Jun 2004 15:05:29 +1000


Hello,

I'm in the process of writing a Clean version of my ICFP2004 programming 
contest solution, to compare with the Haskell and O'CAML versions I've 
already got. Being a Clean newbie, I have a couple of questions about 
using uniqueness types.


First question: How do you create a (large) array when the elements are 
of unique type?

An example of this problem is marked with -->AAAA<-- in the following 
code. I assume that I need a version of createArray which makes copies 
of the default value instead of sharing it among all the elements, but I 
couldn't find one. I suppose I could write my own, but I would still 
need some sort of copy :: *a -> *a function.

I see this mentioned under "Uniqueness Issues" on the Clean Wish list.. 
is there a way around this problem at the moment?


Second question: Is the strictness analyser friends with the uniqueness 
typer?

After defining my Terrain / Cell data-type, it seems like the only way 
to update a (unique) cell is a record update via the top level Terrain 
type. (marked with -->BBBB<--)

I couldn't work out a way to define a *Cell -> *Cell function then take 
one cell of the terrain, transform it with the function, then update the 
terrain with the transformed cell.

I can understand why this would be if the update was being evaluated 
lazilly, but I defined the data-type, the transforming (addFood) 
function _and_ the Terrain record update to be strict and I don't see 
why it shouldn't work.
 
On the other hand, if you introduce a new let-before binding (newFood) 
it works fine. Shouldn't the compiler do basically the same thing?

I think I also see this mentioned under "Uniqueness Issues" on the Clean 
Wish list.. am I having this problem or do I just not know what I'm doing?

...
I realise I can solve both of these problems by making the Cell.mark 
array non-unique, and thus keeping the Cell type non-unique.. but I was 
hoping to make use of the uniqueness typing to beat the run-time 
performance of my Haskell/GHC version. </bait> :)


----------------------------------- ant.icl
module ant

import StdEnv

:: *Terrain     =
    { name    :: !String
    , cell    :: !*{!Cell}
    }
   
:: *Cell     =
    { kind    :: !String
    , food    :: !Int
    , mark    :: !*{Bool}
    }
   

Start :: *World    -> *World
Start     world
 #!
    (console, world)   = stdio world
   
    cell0              =
         { kind        = "Clear"
         , food        = 0
         , mark        = { False, False, False }
         }

    terrain            =
        { name         = "narnia"
        , cell         = createArray 100 cell0        //  -->AAAA<--: 
how to copy cell0?
        }

    // -->BBBB<---
/*
    // this doesn't work
    terrain            =
        { terrain
        & cell.[0]     = addFood 5 terrain.cell.[0]
        }

    // nor this ??
    terrain            =
        { terrain
        & cell.[0].food = terrain.cell.[0].food    + 5 }
*/

    // forcing newFood to be strict works
    newFood            = terrain.cell.[0].food + 5
    terrain            =
        { terrain
        & cell.[0].food    = newFood }


    (str, terrain)     = showTerrain terrain
    console            = fwrites str console
   
    (ok, world)        = fclose console world
   
 =    world
   
   
showCell ::     !*Cell        -> (String, *Cell)
showCell        cell
 #!
     str    =   "("  +++ cell.kind
            +++ ", " +++ toString cell.food +++ ")"
       
 =   (str, cell)


addFood  ::     !Int    !*Cell     -> *Cell
addFood         count    cell      = { cell & food = cell.food + count }

 
showTerrain :: !*Terrain    -> (String, *Terrain)
showTerrain    terrain   
 #!
     str    = "("    +++ terrain.name +++ ")"

 =    (str, terrain)