2015-09-07 96 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}一樣。如果我是對的,那麼我也必須以某種方式「更新」「字典字段」,儘管我不知道如何去做。問題是,是否有類型類參與時使用記錄更新語法的方法?

回答