次の小さな問題が発生しました。制限付きGADTレコードでレコードの更新構文を使用する
{-# LANGUAGE GADTs #-}
data Test a where
Test :: {someString :: String, someData :: a} -> Test a
は、今私はsomeData
ための異なるタイプの新しいTest
値を作成したいのですが、someString
(の同じ値は、レコード更新構文の使用を正当化するために:私はGADTsと一緒に、Haskellのレコード構文を使用しています):
test :: Test a -> Test Bool
test t = t {someData = True}
私はTest
コンストラクタに別のフィールドを追加すると仮定します。そして、
data Test a where
Test :: {someString :: String, someData :: a, someMoreData :: a} -> Test a
私は私のコードは、タイプ-正しい維持するために両方のフィールドを変更する必要があります。
test :: Test a -> Test Bool
test t = t {someData = True, someMoreData = False}
今まで、私はGADTを必要としなかったが、今私は、たとえば、データ型に型クラス制約を追加しますEq
:
data Test a where
Test :: Eq a => {someString :: String, someData :: a} -> Test a
「更新」にsomeData
フィールドをしようとすると、最初の例のように、私は突然、コンパイラエラーを取得:
Couldn't match type ‘a’ with ‘Bool’
‘a’ is a rigid type variable bound by
the type signature for test :: Test a -> Test Bool at Test.hs:18:9
Expected type: Test Bool
Actual type: Test a
Relevant bindings include
t :: Test a (bound at Test.hs:19:6)
test :: Test a -> Test Bool (bound at Test.hs:19:1)
In the expression: t
In the expression: t {someData = True}
私は、これは同じ「Pであることを疑います2つのフィールドがタイプa
であるが、もう少し暗黙的である。私はフィールドの{eqDict :: Eq a}
を持っていたかのように、Eq
タイプのクラスの辞書がコンストラクタの引数のように扱われると思います。私が正しいとすれば、私はこれをどうやって行うのかわからないが、何とか「辞書フィールド」を「更新」しなければならなかった。問題は、型クラスがこのように関わっているときに、レコード更新構文を使用する方法があるかどうかです。
あまりにも悪いですが、私は私の回避策に固執しなければならないと思います。迅速なご回答をありがとうございました。 –