现在,我相信 thawData 的类型专门用于这种情况
thawData :: SomeData a -> ST s (STArray Int a)
不完全是,STArray
s 由状态类型参数化,所以它是ST s (STArray s Int a)
. 但这无法推断,因为错误消息告诉您:
Thaw.hs:13:11:
No instance for (MArray u0 a (ST s))
arising from a use of `thawData'
The type variable `u0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance MArray (GHC.Arr.STArray s) e (ST s)
-- Defined in `Data.Array.Base'
instance MArray (Data.Array.Base.STUArray s) Bool (ST s)
-- Defined in `Data.Array.Base'
instance MArray (Data.Array.Base.STUArray s) Char (ST s)
-- Defined in `Data.Array.Base'
...plus 15 others
Possible fix: add an instance declaration for (MArray u0 a (ST s))
In a stmt of a 'do' block: xArr <- thawData x
有几个可能的MArray
类实例ST s
作为 monad 可供选择(即使只有一个实例在范围内,编译器也会在开放世界假设下运行,其他实例可以在其他地方定义)。所以编译器不知道要使用哪个实例,因此它拒绝编译代码。
现在,建议的可能修复在这里不正确,您需要通过另一种方式修复数组类型。thawData
一种可能性是像您一样在顶层专门化类型签名。
另一种是专攻它doSomething
,
doSomething :: SomeData a -> ()
doSomething x = runST $ do
xArr <- (thawData :: SomeData b -> ST s (STArray s Int b)) x
return ()
它告诉编译器在thawData
这里使用哪种类型,第三个是将表达式类型签名移动到该行的末尾
{-# LANGUAGE ScopedTypeVariables #-}
-- imports etc.
doSomething :: forall a. SomeData a -> ()
doSomething x = runST $ do
xArr <- thawData x :: ST s (STArray s Int a)
return ()
但这需要ScopedTypeVariables
扩展,因为现在您需要引用a
从doSomething
. 不过,我发现它比行中间的表达式类型签名更具可读性。