3

Haskell でポリモーフィズムのある STArray を使用することについて混乱しています。

次の設定があるとします

data SomeData a = Something a

thawData :: MArray u a m => SomeData a -> m (u Int a)
thawData = {- doesn't matter -}

doSomething :: SomeData a -> ()
doSomething x = runST $ do 
  xArr <- thawData x
  return ()

今、私は thawData のタイプがこの場合に特化していると信じています

thawData :: SomeData a -> ST s (STArray Int a)

ただし、do 式の本体で明示的に入力しようとしても、明示的に STArray を使用するように thawData の型を変更しない限り、これはコンパイルされません。

一体何が起こっているのでしょうか?タイプを特化できないのはなぜですか?
thawData の型ではなく、doSomething の本体を何らかの方法で変更できますか?

ありがとう!

4

2 に答える 2

3

今、私はthawDataのタイプがこの場合に特化していると信じています

thawData :: SomeData a -> ST s (STArray Int a)

完全ではありませんが、STArraysは状態タイプによってパラメーター化されるため、になります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つしかない場合でも、コンパイラは開世界仮説で動作し、他のインスタンスは別の場所で定義できます)。したがって、コンパイラは使用するインスタンスを認識しないため、コードのコンパイルを拒否します。

さて、提案された可能な修正はここでは正しいものではありません。必要なのは、別の方法で配列型を修正することです。thawData1つの可能性は、あなたが行ったように、トップレベルでの型署名を特殊化することです。

もう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型変数をインスタンス化する型を参照する必要があるため、拡張が必要です。ただし、行の途中にある式タイプの署名よりも読みやすいと思います。adoSomething

于 2012-12-22T23:18:06.710 に答える
0

エラーメッセージを含めていただければ助かります。

現状では、エラーの原因は、 の型を判別するのに十分なコンテキストを提供していないためだと推測することしかできませんxArr。特に、は引数の型とm統合でき、引数の型から取得できますが、 を決定するためのコンテキストはありません。ST sau

私の推測では、それはコンパイラがあなたに伝えているエラーですが、あなたはそれを含めていないので、それは単なる推測です.

私が正しければthawData、型注釈xArrまたはそれを作成する式を変更せずに、どの型を指定するかを指定することで、これを解決できuます。

于 2012-12-22T22:42:21.660 に答える