<div dir="ltr">(re-sending with "reply to all")<div><br></div><div><span style="font-size:12.8px">If I understand you correctly, you want to create updates to your hash function throughout execution of your program. If this is the case, based on my own experience, I believe the ST monad was not designed for this purpose and so I think it is probably impossible. You must use the IO monad for a hash table that receives regular updates during program execution.</span><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">ST is designed for doing rapid construction of a large immutable data by evaluating many stateful updates to structure during the time before it is made immutable. When monad evaluation terminates, the data structure becomes immutable. Furthermore, you may not use the immutable data structure until the ST evaluation terminates, producing the pure value.<div><br></div><div>For something like a game, you need to take input then update a hash in an event loop. The IO monad is a good model of this sort of behavior, but the ST monad is not.<div><br></div><div>Another possibility is that you can use a pure binary tree structure such as Data.Map, if you would prefer to maintain purity, and pass this Map structure around in a State monad transformer. If your State monad transformer is of type (StateT (Map k v) IO a), you can use "liftIO" to take inputs, and the "modify" function to update the Map state after each input.</div></div><div><br></div></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Dec 30, 2017 at 1:05 AM, Jean-Marc Alliot <span dir="ltr"><<a href="mailto:jm@alliot.org" target="_blank">jm@alliot.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
  
    
  
  <div text="#000000" bgcolor="#FFFFFF">
    <div class="m_-2062882854476857859moz-cite-prefix">Well I am going to try to explain why I
      want to use STArrays and the runST function (and I am absolutely
      ready to be proven wrong, and directed to a better way to do it).<br>
      <br>
      I have, as a simple way to learn the language, implemented an
      Awele program in Haskell (I have been programming games for
      years). It was easy, elegant (around 70 lines, 150 with the
      graphical interface) and completely functional, but I soon
      stumbled upon one problem. While implementing a vanilla alpha-beta
      is easy in functional style, implementing hash-tables (I mean
      hash-tables of the kind we use in game programming, not exactly
      regular hash-tables) is not that easy, and hash tables are
      mandatory to have a fast alpha-beta.<br>
      <br>
      Currently, my idea is to create a module which will hide the
      implementation, and have only two functions in its interface: <br>
      1) A test_and_retrieve which take as only parameter a position and
      return a Maybe object which contains Nothing if the position has
      never been evaluated or (Just v) if there is already an evaluation
      for it (I know that I need more information than just a value, but
      for the sake of simplicity let's stick with just a value)<br>
      2) A store function which will take a position and its evaluation
      and store it in the table.<br>
      <br>
      Now if I use IO Arrays, I will have to live in the IO Monad if I
      understand correctly how the IO Monad works, while using ST Arrays
      seems to give me the possibility to hide all the non functional
      code in my hash module, and keep my main code almost purely
      functional.<div><div class="h5"><br>
      <br>
      Le 29/12/2017 à 16:36, Ramin Honary a écrit :<br>
    </div></div></div><div><div class="h5">
    <blockquote type="cite">
      <div dir="ltr">
        <div>You should use "runSTArray" or "runSTUArray" instead of
          "runST" to convert your STArray to an immutable array:  <a href="https://hackage.haskell.org/package/array-0.5.2.0/docs/Data-Array-ST.html#v:runSTUArray" target="_blank">https://hackage.<wbr>haskell.org/package/array-0.5.<wbr>2.0/docs/Data-Array-ST.html#v:<wbr>runSTUArray</a></div>
        <div><br>
        </div>
        <div>Or another option is to use "stToIO"  to convert the
          "STArray" to an "IOArray." <a href="https://hackage.haskell.org/package/base-4.10.1.0/docs/Control-Monad-ST-Lazy.html#v:stToIO" target="_blank">https://hackage.<wbr>haskell.org/package/base-4.10.<wbr>1.0/docs/Control-Monad-ST-<wbr>Lazy.html#v:stToIO</a> 
          but if you want to build an IOArray, it is better to just
          start with an IOArray rather than converting an STArray to an
          IOArray.</div>
        <div><br>
        </div>
        The design of ST arrays is to allow you to construct them
        quickly and then make them immutable once you are done
        constructing it.
        <div><br>
        </div>
        <div>An immutable array must have the whole array copied after
          every single update, but ST arrays allow you to make many
          updates without copying, then when you have completed
          constructing the ST array, you must freeze it to an immutable
          array using the "runSTUArray" function. Freezing happens
          without copying the array, after that it is immutable and may
          not be made into an STArray again unless you unfreeze it using
          "thaw", which creates a copy of it:  <a href="https://hackage.haskell.org/package/array-0.5.2.0/docs/Data-Array-MArray.html#v:thaw" target="_blank">https://hackage.haskell.<wbr>org/package/array-0.5.2.0/<wbr>docs/Data-Array-MArray.html#v:<wbr>thaw</a>
          <div><br>
          </div>
          <div>Once you have constructed your immutable array, you can
            access it arbitrarily using the immutable operator (!).</div>
          <div><br>
          </div>
          <div>If you want to make multiple updates at multiple times,
            you must use an IOArray or IOUArray. The ST monad is
            designed for you to construct pure, referentially
            transparent, immutable values in an isolated and strictly
            evaluated "environment" that lets you perform strict updates
            during construction. Once evaluation of the "ST" monad is
            complete, the returned value becomes pure, immutable, and
            referentially transparent. The for-all'd "s" parameter of
            the "runST" function ensures you do not mix separate
            "environments," and this is the reason you got your type
            error. Using "runSTArray" or "runSTUArray" does not have
            this restriction.</div>
          <div><br>
          </div>
          <div>I am not sure of the reason for this design decision, but
            I know it has something to do with the compiler guaranteeing
            that pure immutable referentially transparent types are
            constructed without effecting each other, preventing race
            conditions. There is discussion of this on the Haskell
            wiki:  <a href="https://wiki.haskell.org/Monad/ST#An_explanation_in_Haskell-Cafe" target="_blank">https://wiki.haskell.<wbr>org/Monad/ST#An_explanation_<wbr>in_Haskell-Cafe</a><br>
          </div>
          <div><br>
          </div>
        </div>
      </div>
      <div class="gmail_extra"><br>
        <div class="gmail_quote">On Fri, Dec 29, 2017 at 11:36 PM,
          Jean-Marc Alliot <span dir="ltr"><<a href="mailto:jm@alliot.org" target="_blank">jm@alliot.org</a>></span> wrote:<br>
          <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
            <br>
            This is my first post to this list so I apologize in advance
            if I don't use it properly, or if my question is too simple
            or inapropriate.<br>
            <br>
            I come from the Caml world and I am quite new to Haskell
            (but not to functional programming). I am currently trying
            to get the hang of Haskell arrays. I have gone through
            regular arrays, IO Arrays and I am now working with ST
            Arrays.<br>
            <br>
            This is the problem I am currently stuck with. I write the
            following code:<br>
            <br>
            arr = newArray (-1, 1) 0 :: ST s (STArray s Int Int)<br>
            get :: Int -> Int<br>
            get i = runST (arr >>= (\b -> readArray b i))<br>
            <br>
            Here everything is perfectly OK.<br>
            <br>
            Now I want a more general version that could deal with any
            array like arr. So I write:<br>
            <br>
            get2 :: ST s (STArray s Int Int) -> Int -> Int<br>
            get2 tab i = runST (tab >>= (\b -> readArray b i))<br>
            <br>
            And the compiler is clearly very upset by my code:<br>
            <br>
            Couldn't match type ‘s’ with ‘s1’<br>
                  ‘s’ is a rigid type variable bound by<br>
                    the type signature for:<br>
                      get2 :: forall s. ST s (STArray s Int Int) ->
            Int -> Int<br>
                    at testst.hs:17:9<br>
                  ‘s1’ is a rigid type variable bound by<br>
                    a type expected by the context:<br>
                      forall s1. ST s1 Int<br>
                    at testst.hs:18:14<br>
                  Expected type: ST s1 Int<br>
                    Actual type: ST s Int<br>
            I am pretty sure that the compiler is right and I am wrong,
            but I don't get why... Anyone could help?<br>
            <br>
            Thanks<br>
            <br>
            <br>
            ______________________________<wbr>_________________<br>
            Haskell-Cafe mailing list<br>
            To (un)subscribe, modify options or view archives go to:<br>
            <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bi<wbr>n/mailman/listinfo/haskell-caf<wbr>e</a><br>
            Only members subscribed via the mailman list are allowed to
            post.</blockquote>
        </div>
        <br>
      </div>
    </blockquote>
    <p><br>
    </p>
  </div></div></div>

<br>______________________________<wbr>_________________<br>
Haskell-Cafe mailing list<br>
To (un)subscribe, modify options or view archives go to:<br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-<wbr>bin/mailman/listinfo/haskell-<wbr>cafe</a><br>
Only members subscribed via the mailman list are allowed to post.<br></blockquote></div><br></div>