Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Unforunately, you can't currently create a context that requires that an unboxed array be available for a specific type. Quantified Constraints aren't allowed. However, you can still accomplish what you're trying to do, (with the added advantage of having type-specific code versions.) For Longer functions, you could try to split out common expressions so that the repeated code is as small as possible.</p> <pre><code>{-# LANGUAGE FlexibleContexts, ScopedTypeVariables #-} module AccumST where import Control.Monad import Control.Monad.ST import Data.Array.Unboxed import Data.Array.ST import Data.Array.IArray -- General one valid for all instances of Num. -- accumST :: forall a. (IArray UArray a, Num a) =&gt; [a] -&gt; Int -&gt; a accumST :: forall a. (IArray UArray a, Num a) =&gt; [a] -&gt; Int -&gt; a accumST vals = (!) . runSTArray $ do arr &lt;- newArray (0, length vals) 0 :: (Num a) =&gt; ST s (STArray s Int a) forM_ (zip vals [1 .. length vals]) $ \(val, i) -&gt; readArray arr (i - 1) &gt;&gt;= writeArray arr i . (+ val) return arr accumSTFloat vals = (!) . runSTUArray $ do arr &lt;- newArray (0, length vals) 0 :: ST s (STUArray s Int Float) forM_ (zip vals [1 .. length vals]) $ \(val, i) -&gt; readArray arr (i - 1) &gt;&gt;= writeArray arr i . (+ val) return arr accumSTDouble vals = (!) . runSTUArray $ do arr &lt;- newArray (0, length vals) 0 :: ST s (STUArray s Int Double) forM_ (zip vals [1 .. length vals]) $ \(val, i) -&gt; readArray arr (i - 1) &gt;&gt;= writeArray arr i . (+ val) return arr {-# RULES "accumST/Float" accumST = accumSTFloat #-} {-# RULES "accumST/Double" accumST = accumSTDouble #-} </code></pre> <p>The Generic Unboxed version (which doesn't work) would have a type constraint like the following:</p> <pre><code>accumSTU :: forall a. (IArray UArray a, Num a, forall s. MArray (STUArray s) a (ST s)) =&gt; [a] -&gt; Int -&gt; a </code></pre> <p>You could simplify as follows:</p> <pre><code>-- accumST :: forall a. (IArray UArray a, Num a) =&gt; [a] -&gt; Int -&gt; a accumST :: forall a. (IArray UArray a, Num a) =&gt; [a] -&gt; Int -&gt; a accumST vals = (!) . runSTArray $ do arr &lt;- newArray (0, length vals) 0 :: (Num a) =&gt; ST s (STArray s Int a) accumST_inner vals arr accumST_inner vals arr = do forM_ (zip vals [1 .. length vals]) $ \(val, i) -&gt; readArray arr (i - 1) &gt;&gt;= writeArray arr i . (+ val) return arr accumSTFloat vals = (!) . runSTUArray $ do arr &lt;- newArray (0, length vals) 0 :: ST s (STUArray s Int Float) accumST_inner vals arr accumSTDouble vals = (!) . runSTUArray $ do arr &lt;- newArray (0, length vals) 0 :: ST s (STUArray s Int Double) accumST_inner vals arr {-# RULES "accumST/Float" accumST = accumSTFloat #-} {-# RULES "accumST/Double" accumST = accumSTDouble #-} </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload