Sorry, I was lazy. New maximum':<br><span style="font-family: courier new,monospace;">maximum' = foldl1' max</span><br><br><div><span class="gmail_quote">On 02/02/2008, <b class="gmail_sendername">Rodrigo Queiro</b> <<a href="mailto:overdrigzed@gmail.com">overdrigzed@gmail.com</a>> wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
This is my attempt at some nicer code:<br><br><span style="font-family: courier new,monospace;">maximum' (x:xs) = foldl' max x xs</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">maximum' _ = undefined</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">modifyArray :: (MArray a e m, Ix i) => (e -> e) -> a i e -> m ()</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">modifyArray fn arr = do</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> bounds <- getBounds arr</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> forM_ (range bounds) (modifyElement fn arr)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">modifyElement :: (MArray a e m, Ix i) => (e -> e) -> a i e -> i -> m ()</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">modifyElement fn arr i = do</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> x <- readArray arr i</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> writeArray arr i (fn x)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">normalizeArray :: (MArray a e m, Ix i, Fractional e, Ord e) => a i e -> m ()</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">normalizeArray arr = do</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> arr_elems <- getElems arr</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> let max_elem = maximum' arr_elems</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> modifyArray (/max_elem) arr</span><div>
<span class="e" id="q_117da395b75f47e0_1"><br>
<br>On 02/02/2008, Jeff φ <<a href="mailto:jeff1.61803@gmail.com" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">jeff1.61803@gmail.com</a>> wrote:<br>> Hello,<br>> <br>> I'm trying to write code that will take a mutable 2D array and normalize it<br>
> by dividing all elements by the largest element. <br>> <br>> I managed to write code to do this, but it seems overly complex. I could<br>> write something much simpler in Clean or C++. Most likely, my code is<br>
> complex because I don't have any experience with mutable arrays in Haskell. <br>> I couldn't find any tutorials on the Internet. I'd be grateful for<br>> suggestions on simplifying the following code. Thanks.<br>
> <br>> <br>> {-# OPTIONS_GHC -fglasgow-exts -fbreak-on-exception #-}<br>> <br>> -- normalize_ary This takes a mutable array. Determines the largest<br>> -- element in the array (max_elem) and then divides every element by<br>
> -- max_elem.<br>> normalize_ary :: (Num t1,<br>> Num t,<br>> Ix t,<br>> Ix t1,<br>> MArray a e t2,<br>> Ord e,<br>
> Fractional e,<br>> Enum t,<br>> Enum t1) =><br>> a (t, t1) e -> t2 ()<br>> normalize_ary ary = <br>> do <br>> -- The following two commented out lines of code show my first<br>
> -- attempt at determining a value for max_elem. However, this<br>> -- produces a stack overflow.<br>> <br>> -- elem_ary <- getElems ary <br>> -- let max_elem = foldl1 max elem_ary<br>
> <br>> max_elem <- calc_max_2d_elem ary<br>> max_elem `seq` map_in_place_2d_arr (\x -> x / max_elem) ary<br>> <br>> <br>> map_in_place_2d_arr :: (MArray a e t, Enum t2, Enum t1, Ix t1, Ix t2) =><br>
> (e -> e) -> a (t1, t2) e -> t ()<br>> map_in_place_2d_arr fn arr = ret<br>> where <br>> ret = do ((i1,j1),(i2,j2)) <- getBounds arr<br>> ( mapM_ (\i -> do v <- readArray arr i<br>
> writeArray arr i (fn v)<br>> )<br>> [(i,j) | i <- [i1..i2], j <- [j1..j2]])<br>> <br>> <br>> calc_max_2d_elem :: (Ord t, MArray a t t1, Ix t2, Ix t3, Num t3, Num t2) =><br>
> a (t3, t2) t -> t1 t<br>> calc_max_2d_elem arr = <br>> do m <- readArray arr (0,0)<br>> (_,(i_max, j_max)) <- getBounds arr<br>> let calc_max_loop arr m (i,j)<br>
> | j == j_max = return m<br>> | otherwise = do e <- readArray arr (i,j)<br>> let m2 = max e m<br>> m2 `seq` calc_max_loop<br>
> arr m2 nxt_idx<br>> where nxt_idx | i == i_max - 1 = (0,j+1)<br>> | otherwise = (i+1,j)<br>> calc_max_loop arr m (0,0)<br>> <br>> <br></span></div>> _______________________________________________<br>
> Haskell-Cafe mailing list<br>> <a href="mailto:Haskell-Cafe@haskell.org" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">Haskell-Cafe@haskell.org</a><br>> <a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
> <br>> <br>
</blockquote></div><br>