2012-08-30 23 views
10

Birbirlerini tanımlanmış varsayılan örnek örneklerine sahip olmanın bir yolu var mı?Birbirine ait varsayılan tür örnekleri

{-# LANGUAGE DataKinds, KindSignatures #-} 
{-# LANGUAGE TypeFamilies #-} 
{-# LANGUAGE UndecidableInstances #-} 
data Tag = A | B | C 

class Foo (a :: *) where 
    type Bar a (b :: Tag) 

    type Bar a A =() 
    type Bar a B = Bar a A 
    type Bar a C = Bar a A 

instance Foo Int where 
    type Bar Int A = Bool 

test :: Bar Int B 
test = True 

ama bu işe yaramazsa: Bu çalışma gibi bir şey almaya çalışıyorum

Couldn't match type `Bar Int 'B' with `Bool' 
In the expression: True 
In an equation for `test': test = True 

Not Bu işe yaramazsa o ya:

test :: Bar Int B 
test =() 

cevap

3

Evet, varsayılan tür örnekler birbirinden tanımlanabilir (kendi örneğinizden görebileceğiniz gibi):

instance Foo Int where 
-- So the default recursive definition will be used instead 
-- type Bar Int A = Bool 

test :: Bar Int B 
test =() 
Eğer Int için örnek tanımında tipi eşanlamlı ilişkili yeniden tanımladığınızda

Ancak Bar ait tüm varsayılan 3 satır Definition değiştirin (ve sadece type Bar a A =()) Bar Int B ve Bar Int C artık tanımlanmış demektir bir satır type Bar Int A = Bool ile.

yüzden özyinelemeli Defaults amaçlanan şekilde kullanmak yollarından biri (oldukça ayrıntılı olsa) yerine belirli eş anlamlılarını yeniden tanımlamak için sanırım:

: varsayılan ayarlara geri düşebilir
class Foo (a :: *) where 
    type Bar a (b :: Tag) 
    type Bar a A = BarA a 
    type Bar a B = BarB a 

    type BarA a 
    type BarA a =() 

    type BarB a 
    type BarB a = Bar a A 

-- This now works 
instance Foo Int where 
    type BarA Int = Bool 

test :: Bar Int B 
test = True 

-- As well as this one 
instance Foo Int where 
-- type BarA Int = Bool 

test :: Bar Int B 
test =() 
İlgili konular