了解 Purescript 类型不匹配编译器错误

Understanding Purescript Type Mismatch Compilor Error

问题:

我无法理解这段代码中的错误:

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

错误:

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

它说 t1 是未知类型,但我很确定它应该是 a2。我不确定 t1 是如何或在何处引入的。 thaw 应该 return 类型 ST h (STArray h a) 绑定到 mutableArray :: STArray h a


如果我专门化这个函数,它会变得更清晰但同样令人困惑

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

我收到这个错误:

  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

如果我明确键入左侧,

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

或者不写do符号:

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

错误并没有真正改变。在每种情况下,我都无法理解引入 t1 的位置。

问题:

  1. 我写的有什么问题吗?
  2. 以后遇到类似问题我可以采取哪些步骤自行调试?

您使用的 run 版本错误。

The one you're using 来自 Data.Array.ST.
但是 the one your code assumes 来自 Control.Monad.ST.

前者采用 ST 计算,return 是一个 STArray,然后运行该计算,冻结结果数组,并将其 return 作为一个不可变数组。
后者采用 ST 计算 returns something,然后运行该计算并 returns 结果 something.

您的 do 块正在 returning Array a,但随后您正在调用 Data.Array.ST.run,它需要 STArray h a,因此类型不匹配。这正是错误消息所说的:无法将 Array aSTArray h a 匹配。

修复选项 1:导入另一个 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

修复选项 2:return 来自 do 块的 STArray,不要冻结它:

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