2016-04-28 39 views
6

örtüşen çözmek için nasıl Aşağıdaki kod Tabiiörneği

instance {-# OVERLAPS #-} Transformable a a where 
    transform x = x 

instance {-# OVERLAPPABLE #-} (Transformable l l', Transformable r r') 
     => Transformable (Either l r) (Either l' r') 
    where 
    transform = bimap transform transform 

, bu örnekler ben Either a b için Either a b dönüşümü ve aşağıdaki almaya çalışıyorum durumda üst üste (dönüşümü dönüştürmek için benzerdir) sahip hata mesajı ben OVERLAPS, OVERLAPPING ve OVERLAPPABLE farklı kombinasyonu denedim ama hiçbir şey inşaat

Overlapping instances for Transformable 
           (parsingerror text) (parsingerror text) 
     arising from a use of ‘makereceipt’ 
    matching instances: 
Matching instances: Overlapping instances for Transformable 
          (ParsingError Text) (ParsingError Text) 
    arising from a use of ‘makeReceipt’ 
Matching instances: 
    instance [overlappable] (Transformable l l', Transformable r r') => 
          Transformable (Either l r) (Either l' r') 
     instance [overlappable] (Transformable l l', Transformable r r') => 
           Transformable (Either l r) (Either l' r') 
     -- Defined at Handler/GLEnterReceiptSheet/ReceiptRow.hs:154:31 
     instance [overlap ok] Transformable a a 
     -- Defined at Handler/GLEnterReceiptSheet/ReceiptRow.hs:151:27 

(ParsingErrorEither something somethingElse için bir tür diğer adıdır). Bunu Nasıl Çözebilirim ?

class Transformable a b where 
    transform :: a -> b 

-- this one 
instance {-# OVERLAPS #-} (a ~ b) => Transformable a b where 
    transform x = x 

instance (Transformable l l', Transformable r r') 
     => Transformable (Either l r) (Either l' r') where 
    transform = either (Left . transform) (Right . transform) 

test0 :: (Transformable a a', Transformable b b') => Either a b -> Either a' b' 
test0 = transform 

Ve kod olursa olsun, hangi çalışmak diğer örneği kullanmak çakışacak:

cevap

7

Sen örneği tanımlardan biri değişmek zorunda kalacaktır. İkinci örnekte aslında hiç pragmaya ihtiyacınız yok.

orijinal kod ile sorun örnekleri aslında sadece örtüşen tutarsız, değildir, bu nedenle {-# OVERLAPS/OVERLAPPING/OVERLAPPABLE #-} hiçbir kombinasyonunun kurtaracak edeceğini - eğer arzu değildir {-# INHCOHERENT #-} kullanmak gerekir ve ben tavsiye etmem . GHC hata iletisinde bu tutarsızlıkla ilgili söyleyecektir:

>:t transform :: (Transformable a a', Transformable b b') => Either a b -> Either a' b' 

<interactive>:1:1: Warning: 
    Overlapping instances for Transformable 
           (Either a1 b1) (Either a'1 b'1) 
     arising from a use of `transform' 
    Matching instances: 
     instance [overlappable] (Transformable l l', Transformable r r') => 
           Transformable (Either l r) (Either l' r') 
     -- Defined at test6.hs:9:31 
     instance [overlap ok] Transformable a a -- Defined at test6.hs:6:27 
    (The choice depends on the instantiation of `a1, b1, a'1, b'1' 
    To pick the first instance above, use IncoherentInstances 
    when compiling the other instance declarations) 
    In the expression: 
     transform :: 
      (Transformable a a', Transformable b b') => 
      Either a b -> Either a' b' 

Esasen, örtüşen durumlarda seçim yapmak üzere, bir örneği eşleşmesini çalıştığınız tip (ler) için "en özel" olması gerekir. Bunun detayları user guide'da verilmektedir.

+2

Kullanıcı kılavuzunu okumaya çalıştım ama hiçbir şey anlamadım. 'A a' ve 'a ~ b =' 'Dönüştürülebilir a' 'arasındaki farkı açıklayabilir misiniz? Benim için aynı görünüyorlar. – mb14

+0

@ mb14, 'OverlappingInstances' için belgelerin karmaşıklığı, beni kötü bir fikir olduğuna ikna eden şeylerden biri. O zamandan beri, her türlü iyi sezgiyi kırarak, “müdahaleci” olduğuna dair bir kanıt buldum. Ben hiç bir hayranı değilim. – dfeuer

+0

@dfeur Katılıyorum, ancak bu durumda gerçekten bir seçeneğim yok. En sinir bozucu, örtüşen bu örneklerin gerçekte uygulamaya sahip olmasıdır, dolayısıyla uygulamada çakışma yoktur. Ayrıca, her iki durumda da eşitsizlik kısıtlaması ekleyebilirsem bu soruna sahip olmazdım. – mb14