[clean-list] Again: Strong root normal form

Pieter Koopman pieter@cs.kun.nl
Mon, 14 Oct 2002 10:14:14 +0200


--=====================_435201686==_.ALT
Content-Type: text/plain; charset="us-ascii"; format=flowed

Hi,

At 09:25 14-10-2002 +0200, Erik Zuurbier wrote:
>Below is an example of Clean 1.3.2 code that frustrates me. fun is the 
>first attempt. I understand (but do not appreciate) why it does not 
>uniqueness-typecheck. fun1 and fun2 are attempts to cure this. I don't 
>understand why these attempts do not work, and I would not know what 
>would. Hope someone can help.
>
>myArr :: {Int}
>myArr = {1,2,3,4,5,6,7,8,9}
>
>Start = fun myArr 3
>
>fun :: {Int} Int -> (Int,{Int})
>fun arr i
>         # e = if (i>0) arr.[i-2] undef
>         = (e,{arr & [i] = 2*e})

There are many ways to do this. The key step is to make the array argument 
of fun unique. It must be unique in order to allow the array update. This 
requires that myArr can be treated as a unique array, hence its type should 
be .{Int} (or *{Int}).

Furthermore you should take care that the array is unique within the 
function. This can be done by passing it around (as is done in fun and fun 
1 below), or by using a strict let in order to be sure that the array 
selection is done before the update (as in fun2).

myArr :: .{Int}
myArr = {1,2,3,4,5,6,7,8,9}

Start = fun2 myArr 3

fun :: *{Int} Int -> (Int,*{Int})
fun arr i
     | i>0
         # (e,arr) = arr![i-2]
         = (e,{arr & [i] = 2*e})
     | otherwise
         = (undef,arr)

fun1 :: *{Int} Int -> (Int,*{Int})
fun1 arr i
     # (e,arr) = if (i>0) arr![i-2] undef
     = (e,{arr & [i] = 2*e})

fun2 :: *{Int} Int -> (Int,*{Int})
fun2 arr i
     #! e = if (i>0) arr.[i-2] undef
     = (e,{arr & [i] = 2*e})

Have fun,
Pieter Koopman
--=====================_435201686==_.ALT
Content-Type: text/html; charset="us-ascii"

Hi,

At 09:25 14-10-2002 +0200, Erik Zuurbier wrote:
Below is an example of Clean 1.3.2 code that frustrates me. fun is the first attempt. I understand (but do not appreciate) why it does not uniqueness-typecheck. fun1 and fun2 are attempts to cure this. I don't understand why these attempts do not work, and I would not know what would. Hope someone can help.

myArr :: {Int}
myArr = {1,2,3,4,5,6,7,8,9}

Start = fun myArr 3

fun :: {Int} Int -> (Int,{Int})
fun arr i
        # e = if (i>0) arr.[i-2] undef
        = (e,{arr & [i] = 2*e})

There are many ways to do this. The key step is to make the array argument of fun unique. It must be unique in order to allow the array update. This requires that myArr can be treated as a unique array, hence its type should be .{Int} (or *{Int}).

Furthermore you should take care that the array is unique within the function. This can be done by passing it around (as is done in fun and fun 1 below), or by using a strict let in order to be sure that the array selection is done before the update (as in fun2).

myArr :: .{Int}
myArr = {1,2,3,4,5,6,7,8,9}

Start = fun2 myArr 3

fun :: *{Int} Int -> (Int,*{Int})
fun arr i
    | i>0
        # (e,arr) = arr![i-2]
        = (e,{arr & [i] = 2*e})
    | otherwise
        = (undef,arr)

fun1 :: *{Int} Int -> (Int,*{Int})
fun1 arr i
    # (e,arr) = if (i>0) arr![i-2] undef
    = (e,{arr & [i] = 2*e})

fun2 :: *{Int} Int -> (Int,*{Int})
fun2 arr i
    #! e = if (i>0) arr.[i-2] undef
    = (e,{arr & [i] = 2*e})

Have fun,
Pieter Koopman --=====================_435201686==_.ALT--