[clean-list] Updating unique structures in unique structures
in unique structures
John van Groningen
johnvg at cs.ru.nl
Wed May 7 17:18:12 MEST 2008
Norbert Zeh wrote:
>When I first got to know Clean, I came from the Haskell side and was impressed that Clean had found a way to make array updates efficient while maintaining referential transparency. Now I've run into my first round of problems with unique objects, and I'd appreciate some help. Here's what I want to do. I want to define a record type one of whose fields is an array, and I want to be able to update the array. So the array has to be unique and, therefore, the record type has to be unique:
>
>:: *A = { id :: Int
> , a :: *{Int}
> }
>
>In a unique array of unique arrays, I could use the replace function to get a unique reference to one of the arrays stored in the outer array. My question is: Is there a similar way to get a unique reference to the elements of a record?
A unique element of a record can be updated by selecting and updating
the element in the same function. For example:
f r = {r & a = some_update_function r.a}
However because of limitations in the implementation of the reference analysis
of uniqueness typing, a unique element cannot be selected using a ! selection
and cannot be updated using a nested update.
So to select a unique element use a pattern match or a . selection.
For example use:
f r=:{a}
= {r & a = some_update_function a}
f r
# {a} = r
= {r & a = some_update_function a}
f r
# a = r.a
= {r & a = some_update_function r}
But not:
f r
# (a,r) = r!a
= {r & a = some_update_function a}
To update a unique element in another unique element use for example:
f r=:{v1=v1=:{v2}}
= {r & v1 = {v1 & v2 = some_update_function v2}}
f r
# {v1=v1=:{v2}} = r
= {r & v1 = {v1 & v2 = some_update_function v2}}
f r=:{v1}
= {r & v1 = {v1 & v2 = some_update_function v1.v2}}
f r
# {v1} = r
= {r & v1 = {v1 & v2 = some_update_function v1.v2}}
f r
# v1 = r.v1
= {r & v1 = {v1 & v2 = some_update_function v1.v2}}
:: *R1 = {v1::R2}
:: *R2 = {v2::*{Int}}
But not:
f r
= {r & v1.v2 = some_update_function r.v1.v2}}
>The reason why I'd like to do this is that I have a number of nested unique references of this type. In particular, I have another record type:
>
>:: *B = { id :: Int
> , a :: *{A}
> }
>
>So threading my way through the reference hierarchy makes for rather unreadable code, and I'd like to have a reference to the array inside an A-record to manipulate it and later patch it back into the A-record.
You can do this in the following way (I have renamed field 'a' of B to 'aa'):
f b i
# (aai,aa) = replace b.aa i dummy_a
# new_a = update_a aai.a
= {b & aa = {aa & [i] = {aai & a = new_a}}}
:: *A = { id :: Int
, a :: *{Int}
}
:: *B = { id :: Int
, aa :: *{A}
}
dummy_a :== {id=0,a={}}
update_a :: *{Int} -> *{Int}
update_a a = a
Kind regards,
John van Groningen
More information about the clean-list
mailing list