2012-01-31 14 views
7

Bir bakıma bu, önceki sorumdan geriye doğru bir adımdır, ancak ... Birisi bana neden bu 'un neden çalışmadığını hatırlatır mı?Kapsayıcı öğe türleri

 
class Container c e where 
    empty :: c 
    insert :: e -> c -> c 

instance Container [x] x where 
    empty = [] 
    insert = (:) 

instance Container ByteString Word8 where 
    empty = BIN.empty 
    insert = BIN.cons 

instance Ord x => Container (Set x) x where 
    empty = SET.empty 
    insert = SET.insert 

kolay, kimse fonksiyonel bağımlılıkları ne de ilişkili türleri icat etmek rahatsız olurdu olmasıydı Açıkçası eğer. Peki yukarıdaki sorun nedir?

+0

Kullanmayı deneyin. Yakında belirsiz aşırı yükleme hakkında şikayetler alacaksınız. – augustss

cevap

10

instance Container [Int] Int ve instance Container [Int] Char'u eklemekten sizi durduracak hiçbir şey yoktur ve empty :: [Int] için sorduğunuzda, derleyicinin hangi örneği geleceğini bilmesi mümkün değildir.

"Ah, ama ben sadece instance Container [Int] Int var" diyorsunuz. "Ve bir instance Container [Int] Char zaten bir hata olur."

Ancak derleyici, ileride bir instance Container [Int] Char eklemeyeceğinizi bilemez ve bunu yaparsanız, varolan kodunuzu kırmasına izin verilmez. sadece ikinci tür bakımından farklılık gösteren farklı örneklerini görürse

yüzden

  • Container ilk parametresi benzersiz Container
  • ikinci parametreyi belirleyen derleyici söylüyorum bazı yolu gerekir, gösterir Bir hata

Fonksiyonel bağımlılıklar girin.

+0

Bariz bir şeyi unutmam gerektiğini biliyordum. – MathematicalOrchid