Note that there are some explanatory texts on larger screens.

plurals
  1. PORevisiting Polymorphic STUArrays with Constraint Kinds
    primarykey
    data
    text
    <p>I want to implement a dynamic programming algorithm polymorphic in the score type; here's a simplified 1D version with no boundary conditions:</p> <pre><code>{-# LANGUAGE ConstraintKinds, FlexibleContexts, RankNTypes, ScopedTypeVariables #-} import Control.Monad import Control.Monad.ST.Strict import Data.Array.ST import Data.Array.Unboxed dynamicProgrammingSTU :: forall e i . ( IArray UArray e, forall s. MArray (STUArray s) e (ST s), Ix i ) =&gt; (forall m . Monad m =&gt; (i -&gt; m e) -&gt; (i -&gt; m e)) -&gt; (i, i) -&gt; (i -&gt; e) dynamicProgrammingSTU prog bnds = (arr !) where arr :: UArray i e arr = runSTUArray resultArrayST resultArrayST :: forall s . ST s (STUArray s i e) resultArrayST = do marr &lt;- newArray_ bnds forM_ (range bnds) $ \i -&gt; do result &lt;- prog (readArray marr) i writeArray marr i result return marr </code></pre> <p>The constraint doesn't work;</p> <pre><code> Could not deduce (MArray (STUArray s) e (ST s)) arising from a use of `newArray_' from the context (IArray UArray e, forall s. MArray (STUArray s) e (ST s), Ix i) bound by the type signature for dynamicProgrammingSTU :: (IArray UArray e, forall s. MArray (STUArray s) e (ST s ), Ix i) =&gt; (forall (m :: * -&gt; *). Monad m =&gt; (i - &gt; m e) -&gt; i -&gt; m e) -&gt; (i, i) -&gt; i -&gt; e at example2.hs:(17,1)-(27,15) Possible fix: add (MArray (STUArray s) e (ST s)) to the context of the type signature for resultArrayST :: ST s (STUArray s i e) or the type signature for dynamicProgrammingSTU :: (IArray UArray e, forall s. MArray (STUArray s) e (ST s), I x i) =&gt; (forall (m :: * -&gt; *). Monad m =&gt; (i -&gt; m e) -&gt; i -&gt; m e) -&gt; (i, i) -&gt; i -&gt; e or add an instance declaration for (MArray (STUArray s) e (ST s)) In a stmt of a 'do' block: marr &lt;- newArray_ bnds In the expression: do { marr &lt;- newArray_ bnds; forM_ (range bnds) $ \ i -&gt; do { ... }; return marr } In an equation for `resultArrayST': resultArrayST = do { marr &lt;- newArray_ bnds; forM_ (range bnds) $ \ i -&gt; ...; return marr } Failed, modules loaded: none. </code></pre> <p>To summarize, <code>Could not deduce (MArray (STUArray s) e (ST s)) from the context forall s. MArray (STUArray s) e (ST s i)</code>. Note that adding the constraint to <code>resultArrayST</code> just pushes the problem to <code>runSTUArray</code>.</p> <p>I currently know of four flawed solutions:</p> <ol> <li>Avoiding the problem with boxed <code>STArray</code>s or simply non-monadic <code>Array</code>s, perhaps using <code>seq</code> and bang patterns to ease the resulting memory problems. </li> <li>Breaking the type system with <code>unsafeFreeze</code> and <code>unsafePerformIO</code>, for which the damning constraint <code>MArray IOUArray e IO</code> works fine.</li> <li><a href="https://stackoverflow.com/a/2244281/2036189">This</a> solution to a similar problem using a typeclass and writing instances for every 'unboxable' type.</li> <li><a href="https://stackoverflow.com/a/2224463/2036189">This</a> one using GHC rewrite rules to pick a different function for each type (and a generic <code>STArray</code> version).</li> </ol> <p>However, I'm asking this question in the hopes that modern language extensions like <code>ConstraintKinds</code> can allow me to express my original code's intent of <code>forall s. MArray (STUArray s) e (ST s)</code>.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

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