[clean-list] Updating unique structures in unique structures in unique structures

Norbert Zeh nzeh at cs.dal.ca
Wed May 7 18:14:18 MEST 2008


Thanks a million for the detailed answer.  This helps a lot.

Cheers,
Norbert

On Wed, 7 May 
2008, John van Groningen wrote:

> 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