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

时间:2021-03-08 16:15:59

标签: purescript

问题:

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

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 应该返回绑定到 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. 将来遇到类似问题时,我可以采取哪些步骤来自行调试?

1 个答案:

答案 0 :(得分:2)

您使用了错误版本的 run

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

前者采用返回 STSTArray 计算,然后运行该计算,冻结结果数组,并将其作为不可变数组返回。
后者采用 ST 计算返回 something,然后运行该计算并返回结果 something

您的 do 块返回 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:从 STArray 块中返回 do,不要冻结它:

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