今、私は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
ます(スコープ内にインスタンスが1つしかない場合でも、コンパイラは開世界仮説で動作し、他のインスタンスは別の場所で定義できます)。したがって、コンパイラは使用するインスタンスを認識しないため、コードのコンパイルを拒否します。
さて、提案された可能な修正はここでは正しいものではありません。必要なのは、別の方法で配列型を修正することです。thawData
1つの可能性は、あなたが行ったように、トップレベルでの型署名を特殊化することです。
もう1つは、doSomething
代わりにそれを専門にすることです。
doSomething :: SomeData a -> ()
doSomething x = runST $ do
xArr <- (thawData :: SomeData b -> ST s (STArray s Int b)) x
return ()
これは、ここでどの型thawData
を使用するかをコンパイラーに指示し、3番目は式の型シグネチャをその行の終わりに移動することです。
{-# 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