Reputation: 8022
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.
Upvotes: 0
Views: 60
Reputation: 80734
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
Upvotes: 2