2015-09-07 23 views
7

ile kayıt güncelleştirme sözdizimini kullanarak aşağıdaki küçük sorunla karşılaştım.Kısıtlı GADT kayıtları

{-# LANGUAGE GADTs #-} 

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

Şimdi someData için farklı bir türüne sahip yeni Test değer yaratmak istiyoruz ama someString (aynı değer kaydı güncelleme sözdizimi kullanımını haklı: Ben GADTs birlikte, Haskell rekor sözdizimi kullanıyorum):

Ben Test kurucusuna başka bir alan ekle
test :: Test a -> Test Bool 
test t = t {someData = True} 

varsayalım: Sonra

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

Benim kod tip-doğru tutmak için iki alanı da değiştirmek zorunda:

test :: Test a -> Test Bool 
test t = t {someData = True, someMoreData = False} 

Şu ana kadar, GADT gerek yoktu, ama şimdi örneğin, veri türü için bir tür sınıf kısıtlamasını eklemek istediğiniz Eq:

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

ilk örnekteki gibi, hiç "güncelleme" someData alanını çalışırken, birden bir derleyici hatası alıyorum:

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} 

bu aynı "p olmak şüpheli roblemi "daha önce olduğu gibi, a türünde iki alanla, ama biraz daha örtülü. Eq tür sınıfının sözlüğü, {eqDict :: Eq a} alanım olsaydı, yapıcının argümanı gibi ele alınır. Eğer haklıysam, o zaman nasıl yapacağımı bilmeme rağmen “sözlük alanını” bir şekilde “güncellemek” zorunda kaldım. Soru, tip sınıfları bunun gibi olduğunda kayıt güncelleme sözdizimini kullanmanın bir yolu var mı?

cevap