对受约束的 GADT 记录使用记录更新语法

Using record update syntax with constrained GADT records

我偶然发现了以下小问题。我正在使用 Haskell 记录语法以及 GADTs:

{-# LANGUAGE GADTs #-}

data Test a where 
  Test :: {someString :: String, someData :: a} -> Test a

现在我想为 someData 创建一个不同类型的新 Test 值,但为 someString 创建一个相同的值(以证明使用记录更新语法的合理性) :

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,但现在我想为数据类型添加一个类型-class约束,例如Eq:

data Test a where 
  Test :: Eq a => {someString :: String, someData :: a} -> Test a

当尝试 "update" 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}

我怀疑这与之前的情况 "problem" 相同,有两个 a 类型的字段,但更加隐含。我想 Eq 类型 class 的字典被视为构造函数的参数,就像我有一个字段 {eqDict :: Eq a} 一样。如果我是对的,那么我还必须以某种方式 "update" "dictionary field",尽管我不知道该怎么做。问题是,当像这样涉及 classes 类型时,有没有办法使用记录更新语法?

恐怕这还不可能;有一个 seven year old outstanding feature request.