0

The Problem:

I can't find my way to understand the error in this code:

import Prelude
import Data.Array.ST (STArray, modify, run, thaw, freeze)

mpi :: forall a. Array a -> Array a
mpi array = run do
  mutableArray <- thaw array
  freeze mutableArray

The error:

Could not match type
         
    Array
         
  with type
              
    STArray h0
              

while trying to match type Array a2
  with type STArray h0 t1
while checking that expression (bind (thaw array)) (\mutableArray ->     
                                                      freeze mutableArray
                                                   )                     
  has type ST h0 (STArray h0 t1)
in value declaration mpi

where a2 is a rigid type variable
        bound at (line 0, column 0 - line 0, column 0)
      h0 is a rigid type variable
        bound at (line 9, column 17 - line 11, column 22)
      t1 is an unknown type

It says t1 is an unknown type, but I'm pretty sure it should be a2. I'm not sure how or where t1 is introduced. thaw should return type ST h (STArray h a) which gets bound to mutableArray :: STArray h a


If I specialize this function, it becomes clearer but no less confusing

mpi :: Array Int -> Array Int
mpi array = run do
  mutableArray <- thaw array
  freeze mutableArray

I get this error:

  Could not match type
         
    Array
         
  with type
              
    STArray h0
              

while trying to match type Array Int
  with type STArray h0 t1
while checking that expression (bind (thaw array)) (\mutableArray ->     
                                                      freeze mutableArray
                                                   )                     
  has type ST h0 (STArray h0 t1)
in value declaration mpi

where h0 is a rigid type variable
        bound at (line 9, column 17 - line 11, column 22)
      t1 is an unknown type

If I explicitly type the left-hand side,

mpi :: Array Int -> Array Int
mpi array = run do
  (mutableArray :: STArray _ Int) <- thaw array
  freeze mutableArray

or write it without do notation:

mpi :: Array Int -> Array Int
mpi array = run $ thaw array >>= freeze

The error doesn't really change. In each case, I have trouble understanding where t1 is introduced.

The Question:

  1. What's wrong with what I've written?
  2. What steps could I be taking with similar problems in the future to debug this on my own?

1 Answer 1

2

You're using the wrong version of run.

The one you're using is from Data.Array.ST.
But the one your code assumes is from Control.Monad.ST.

The former takes an ST computation that returns an STArray, and then runs that computation, freezes the resulting array, and returns it as an immutable array.
The latter takes an ST computation that returns something, and then runs that computation and returns the resulting something.

Your do block is returning Array a, but then you're calling Data.Array.ST.run, which expects STArray h a, so the types don't match. This is exactly what the error message says: can't match Array a with STArray h a.

Fix option 1: import the other run:

import Prelude
import Control.Monad.ST (run)
import Data.Array.ST (STArray, modify, thaw, freeze)

mpi :: forall a. Array a -> Array a
mpi array = run do
  mutableArray <- thaw array
  freeze mutableArray

Fix option 2: return the STArray from your do block, don't freeze it:

import Prelude
import Data.Array.ST (STArray, modify, run, thaw, freeze)

mpi :: forall a. Array a -> Array a
mpi array = run do
  mutableArray <- thaw array
  pure mutableArray
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for being so consistently helpful/patient :) ... run (thaw array) works. Now that I look at this again, I can see that it's matching on the expression starting with bind. Which with do notation looks strange at first, but makes a lot more sense in the desugared version. In general, when I'm looking at these type errors and it says "while checking that expression..." the first place to look isn't at the components of that expression but rather the type of the expression at a whole.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.