2015-09-07 140 views
7

我偶然发现了以下小问题。我使用哈斯克尔记录语法,连同GADTs:使用带有约束GADT记录的记录更新语法

{-# 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,但现在我想以一个类型类约束添加到数据类型,例如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 roblem“,就像之前的情况一样,两个字段的类型为a,但更隐含一点。我猜Eq类型的字典被视为构造函数的参数,就像我有一个字段{eqDict :: Eq a}一样。如果我是对的,那么我也必须以某种方式“更新”“字典字段”,尽管我不知道如何去做。问题是,是否有类型类参与时使用记录更新语法的方法?

回答