[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)