<table cellspacing="0" cellpadding="0" border="0" ><tr><td valign="top" style="font: inherit;">Brian wrote:<br>&gt; Really, arrays in Haskell are the most @#!$! confusing thing in the world.<br><br>Hi, Brian. <br>I am having a great difficulty with arrays in Haskell.&nbsp; In the university where I study, functional programming is taught in Clean or in Haskell, depending on the professor who is teaching the subject in a given year. One year ago, when I took functional programming, the professor used Clean in his classes. I had no difficulty in learning how arrays and input/output work in Clean.&nbsp; In the case of arrays, the idea is very simple: One can update arrays, provided that s/he does not try to access the old array. Therefore, one needs to make a copy of any value of the old array that s/he will use before performing the update; the operation that makes copies also provides a new name for the array, that obliterates the old name.&nbsp; In order
 to get a better feeling of the thing, here is the `solvitī function, in Clean and Haskell (you can consider the # as a kind of do):<br><br>// Clean<br>leftSide acc i j n arr | j &gt;= n= (acc, arr);<br>&nbsp;&nbsp; # (v, arr)= arr![j, n];<br>&nbsp;&nbsp;&nbsp;&nbsp; (a, arr)= arr![i, j];<br>&nbsp;&nbsp; = leftSide (acc-v*a) i (j+1) n arr;<br><br>solvit i n arr | i &lt; 0 = arr<br>&nbsp; # (a, arr)= arr![i, i];<br>&nbsp;&nbsp;&nbsp; (acc, arr)= arr![i, n];<br>&nbsp;&nbsp;&nbsp; (v, arr)= leftSide acc i (i+1) n arr;<br>&nbsp; = solvit (i-1) n {arr&amp;[i, n]= v/a};<br><br>-- HASKELL<br>leftSide acc i j n arr | j&gt;n= return acc<br>leftSide acc i j n arr = do<br>&nbsp;&nbsp; v &lt;- readArray arr (j, n+1)<br>&nbsp;&nbsp; a &lt;- readArray arr (i, j)<br>&nbsp;&nbsp; leftSide (acc-v*a) i (j+1) n arr<br><br>solvit i n arr | i&lt;1= return ()<br>solvit i n arr= do<br>&nbsp;&nbsp; a &lt;- readArray arr (i, i)<br>&nbsp;&nbsp; acc &lt;- readArray arr (i,
 n+1)<br>&nbsp;&nbsp; v &lt;- leftSide acc i (i+1) n arr<br>&nbsp;&nbsp; writeArray arr (i, n+1) $! (v/a)<br>&nbsp;&nbsp; solvit (i-1) n arr<br><br>And here comes the reason for writing this article. In the previous version of the Gauss elimination algorithm, I have imported Data.Array.IO. I also wrote a version of the program that imports Data.Array.ST. The problem is that I&nbsp; don't know how to read an STUArray from a file, process it, and write it back to a file. Is it possible to transform it into an IOUArray pro tempore, read it, make it into an STUArray again in order to process it, and bring it back to IOUArray in order to print it? Below,&nbsp; you will find the Gauss elimination program in STUArray (by the way, it is slower than IOUArray). Could you modify the main function so it can read array `arrī from a file, and write the result to a file?&nbsp; Here is the Gauss Elimination for STUArray (the main function is the first one; modify it to
 read the array from a file, and write it back to a file):<br><br>import Control.Monad<br>import Control.Monad.ST<br>import Data.Array.ST<br>import Data.Array.IO <br>import System.IO<br>import System.Random<br>import System (getArgs)<br><br><br>main = do<br>&nbsp;&nbsp;&nbsp;&nbsp; xs &lt;- rnList (1.0,1000.0)<br>&nbsp;&nbsp;&nbsp;&nbsp; args &lt;- getArgs<br>&nbsp;&nbsp;&nbsp;&nbsp; let (n, m)= dims args<br>&nbsp;&nbsp;&nbsp;&nbsp; xx &lt;-&nbsp; stToIO $ do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arr &lt;- newArray_ ((1,1),(n,m+1)) :: <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ST s (STUArray s (Int, Int) Double)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fillArray xs 0.0 (1,n) (1,m)
 arr<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sLU arr n<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; solvit n n arr<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x1 &lt;- readArray arr (1, n+1)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x2 &lt;- readArray arr (1, n+1)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return [x1, x2]<br>&nbsp;&nbsp;&nbsp;&nbsp; print xx<br><br><br>{-&nbsp; -- Other option:<br>main = do<br>&nbsp;&nbsp;&nbsp;&nbsp; xs &lt;- rnList (1.0,1000.0)<br>&nbsp;&nbsp;&nbsp;&nbsp; args &lt;- getArgs<br>&nbsp;&nbsp;&nbsp;&nbsp; let (n, m)= dims args<br>&nbsp;&nbsp;&nbsp;&nbsp; print $ runST $
 do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arr &lt;- newArray_ ((1,1),(n,m+1)) :: <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ST s (STUArray s (Int, Int) Double)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fillArray xs 0.0 (1,n) (1,m) arr<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sLU arr n<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; solvit n n arr<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x1 &lt;- readArray arr (1, n+1)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x2 &lt;- readArray arr (1,
 n+1)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return [x1, x2]<br>-}&nbsp;&nbsp; <br><br>fillArray xs s (i, n) (j, m) arr |&nbsp; i &gt; n= return ()<br>fillArray xs s (i,n) (j, m) arr | i==n &amp;&amp; j&gt;m= do<br>&nbsp; writeArray arr (i, j) $! s<br>&nbsp; return ()<br>fillArray xs s (i, n) (j, m) arr | j &gt; m&nbsp; = do<br>&nbsp;&nbsp; writeArray arr (i, j) $! s<br>&nbsp;&nbsp; fillArray xs 0.0 (i+1, n) (1, m) arr<br>fillArray (val:xs) s (i, n) (j, m) arr= do<br>&nbsp;&nbsp; writeArray arr (i, j) $! val<br>&nbsp;&nbsp; fillArray xs (s+val) (i, n) (j+1, m) arr<br><br>sLU arr n= sIJ 2 1 2 n arr<br><br>sIJ i j k n arr | i &gt; n = return ()<br>sIJ i j k n arr | k &gt; n = sIJ (i+1) i (i+1) n arr<br>sIJ i j k n arr = do<br>&nbsp;{- im &lt;- pmax (j+1) j<br>&nbsp; swap j im 1 -}<br>&nbsp; a &lt;- readArray arr (k, j)<br>&nbsp; forM_ [j..n+1] $&nbsp; \l -&gt; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 ajj &lt;- readArray arr (j, j)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ajl &lt;- readArray arr (j, l)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; akl &lt;- readArray arr (k, l) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; writeArray arr (k, l) $! (akl-a*(ajl/ajj))<br>&nbsp; sIJ i j (k+1) n arr where<br>&nbsp;&nbsp;&nbsp;&nbsp; pmax line imax | line &gt; n = return imax<br>&nbsp;&nbsp;&nbsp;&nbsp; pmax line imax = do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; alj &lt;- readArray arr (line, j)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; aij &lt;- readArray arr (imax, j)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (abs alj)&gt; (abs aij) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; then pmax (line+1) line<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else pmax (line+1) imax<br>&nbsp;&nbsp;&nbsp;&nbsp; swap r s q | q&gt;n+1 = return ()<br>&nbsp;&nbsp;&nbsp;&nbsp; swap r s q | r==s = return ()<br>&nbsp;&nbsp;&nbsp;&nbsp; swap r s q =
 do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arq &lt;- readArray arr (r,q)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; asq &lt;- readArray arr (s,q)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; writeArray arr (s,q) $! arq<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; writeArray arr (r,q) $! asq<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; swap r s (q+1)<br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; <br>leftSide acc i j n arr | j&gt;n= return acc<br>leftSide acc i j n arr = do<br>&nbsp;&nbsp; v &lt;- readArray arr (j, n+1)<br>&nbsp;&nbsp; a &lt;- readArray arr (i, j)<br>&nbsp;&nbsp; leftSide (acc-v*a) i (j+1) n arr<br><br>solvit i n arr | i&lt;1= return ()<br>solvit i n arr= do<br>&nbsp;&nbsp; a &lt;- readArray arr (i, i)<br>&nbsp;&nbsp; acc &lt;- readArray arr (i, n+1)<br>&nbsp;&nbsp; v &lt;- leftSide acc i (i+1) n arr<br>&nbsp;&nbsp; writeArray arr (i, n+1) $! (v/a)<br>&nbsp;&nbsp; solvit (i-1) n arr<br><br>rnList :: (Double, Double) -&gt; IO
 [Double]<br>rnList r=getStdGen&gt;&gt;=(\x-&gt;return(randomRs r x))<br><br>dims [input] = (read input, read input)<br>dims _ = (1000, 1000)<br><br><br><br><br><br>--- On <b>Tue, 11/3/09, brian <i>&lt;briand@aracnet.com&gt;</i></b> wrote:<br><blockquote style="border-left: 2px solid rgb(16, 16, 255); margin-left: 5px; padding-left: 5px;"><br>From: brian &lt;briand@aracnet.com&gt;<br>Subject: Re: [Haskell-cafe] What's the deal with Clean?<br>To: "David Leimbach" &lt;leimy2k@gmail.com&gt;<br>Cc: haskell-cafe@haskell.org<br>Received: Tuesday, November 3, 2009, 7:12 PM<br><br><div class="plainMail">Really, arrays in Haskell are the most @#!$! confusing thing in the world.<br><br>There's a bunch of different array structures.<br><br>I can't tell which one works best, and all I want to do is x[i] = value.<br><br>I thought uvector was the answer, you know, fast unboxed ARRAYs.&nbsp; Imagine my surprise when I saw this<br><br>&nbsp; indexU :: UA e =&gt; UArr e
 -&gt; Int -&gt; e<br><br>&nbsp; O(n). indexU extracts an element out of an immutable unboxed array.<br><br>An array implementation with an order N lookup.&nbsp; huh ??&nbsp; That's not an array, that's a list.&nbsp; I was looking for an array.<br><br>However, I then found in the same hackage:<br><br>&nbsp; readMU :: MUArr e s -&gt; Int -&gt; ST s e<br><br>&nbsp; O(1). readMU reads the element at the specified index of a mutable unboxed array.<br><br>So O(1) for mutable, but O(n) for immutable ? See, confusing...&nbsp; I'm sure there's a really good, lofty type safety, something<br>or other reason for that, that I'm sure I don't care about ;-)<br><br>There's also ST.&nbsp; So why is there a uvector, when there's ST ??<br><br>etc, etc, etc...<br><br>and then there's monads...<br><br>other than that, having fun with haskell :-)<br><br>Brian<br><br><br>On Nov 3, 2009, at 3:42 PM, David Leimbach wrote:<br><br>&gt; <br>&gt; <br>&gt; On Tue, Nov 3, 2009 at
 2:16 PM, Tracy Wadleigh &lt;<a ymailto="mailto:tracy.wadleigh@gmail.com" href="/mc/compose?to=tracy.wadleigh@gmail.com">tracy.wadleigh@gmail.com</a>&gt; wrote:<br>&gt; <br>&gt; I had to implement a ring buffer, and I wanted the code using it to be written in Haskell.&nbsp; I ended up implementing the buffer in C, and wrapping it in FFI from Haskell because implementing a destructive array in Haskell is kind of unwieldy to someone of my experience level.&nbsp; In Clean, it looks like the uniqueness typing allows for destructive updates in a very controlled manner.<br>&gt; <br>&gt; The ST monad provides this functionality. The never-instantiated-in-a-visible-way state parameter of the ST monad provides the "uniqueness" required for doing destructive updates in a pure way.<br>&gt; <br>&gt; Someone suggested that to me on IRC once I'd already cranked out a C implementation with FFI bindings.&nbsp; It's just too easy to use the FFI in Haskell :-)<br>&gt;
 <br>&gt; If we raise the barrier of FFI, more people will use ST!<br>&gt; <br>&gt; Dave<br>&gt; <br>&gt; <br>&gt; <br>&gt; _______________________________________________<br>&gt; Haskell-Cafe mailing list<br>&gt; <a ymailto="mailto:Haskell-Cafe@haskell.org" href="/mc/compose?to=Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>&gt; <a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>&gt; <br>&gt; <br>&gt; _______________________________________________<br>&gt; Haskell-Cafe mailing list<br>&gt; <a ymailto="mailto:Haskell-Cafe@haskell.org" href="/mc/compose?to=Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>&gt; <a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br><br>_______________________________________________<br>Haskell-Cafe mailing list<br><a
 ymailto="mailto:Haskell-Cafe@haskell.org" href="/mc/compose?to=Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br><a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br></div></blockquote></td></tr></table><br>
      <hr size=1><a href="http://ca.promos.yahoo.com/newmail/overview2/"><b>All new Yahoo! Mail - </b></a>Get a sneak peak at messages with a handy reading pane.