2010-04-07 16 views
9

Bu kod iyi derlerSorun tipi sınıfları ve tip aileleri karıştırma

Illegal type synonym family application in instance: 
     b -> (c, Rec a) 
    In the instance declaration for `Sel a s (b -> (c, Rec a))' 
:

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, 
    UndecidableInstances, FlexibleContexts, EmptyDataDecls, ScopedTypeVariables, 
    TypeOperators, TypeSynonymInstances, TypeFamilies #-} 
class Sel a s b where 
    type Res a s b :: * 

instance Sel a s b where 
    type Res a s b = (s -> (b,s)) 

class R a where 
    type Rec a :: * 
    cons :: a -> Rec a 
    elim :: Rec a -> a 
instance Sel a s (b->(c,Rec a)) where 
    type Res a s (b->(c,Rec a)) = (b -> s -> (c,s)) 

şikayet

Bu ne anlama geliyor ve (en önemlisi) bunu nasıl düzeltirim?

Teşekkür

+2

Hayır, 1. parça kod benim için iyi bir derleme yapmıyor. GHC (6.12.1), 'Çakışan aile örneği bildirimleri'ni' şikayet ediyor. – kennytm

cevap

12

Türü aileler tek yönlüdür: hesaplanan türüne Rec a3'ü genişletebilir, ancak genişletme işleminden (benzersiz olarak) Rec a'a geçemezsiniz. Bu, örneğin uygulanacak örneğini hiçbir zaman tetikleyemediği için, örnek imzalamaların örnek imzalar için uygun olmayan uygulamalarını yapar.

yerine deneyebilirsiniz:

instance Rec a ~ reca => Sel a s (b->(c,reca)) 

Bu başka bir şey şu anlama gelir: herhangi işlev b -> (c, reca) bir örnek olduğunu ve geri dönülemez karşıladığında sonra, derleyici denetler Rec a ~ reca söylüyor. Fakat bu sizin durumunuzda isteyecek kadar iyi olabilir.

1

Rec bir tür yapıcı değildir; bu bir tür işlevdir. Belki bunu yalnızca sınıf tanımında değil, tip tanımının bir türünde kullanabilirsiniz. Burada çılgınca tahmin ediyorum; Tür aileleri için tüm kuralları anlamıyorum.

bunu düzeltmek için nasıl bilmiyorum, ama denemek için bazı şeyler şunlardır:

  • sınıf Sel kurtulun ve sadece type family Res a s b :: * tanımlar. Sınıf mekanizması yerine type instance kullanın.

  • data'u kullanarak Rec türünü enjekte etmenin, ancak yardımcı olamayacağını düşünmüyorum, ancak sanmıyorum.

  • — çalışmasına neden olabilecek en küçük dil uzantılarına geri dönmesi, başkalarının size yardımcı olmasını kolaylaştıracak ve derleyiciye de yardımcı olabilir.

+1

'data' işlevini kullanmak işe yarar - örnek ailelerin örnek başlarına izin verilir, oysa eşanlamlı aileler yazın değildir. –

1

Bu, tür örneklerini bildirirken tür eşlemeli aileleri kullanmanıza izin verilmediği anlamına gelir. GHC kullanım kılavuzunun "Type families and instance declarations" bölümüne bakın.

Bunu düzeltmenin tek yolu, bir şekilde buna ihtiyaç duymayacak şekilde refactor yapmaktır.