2010-02-22 23 views
11

Bu özel kod bölümünün amacı, 'daki tüm öğeleri saymadan size işlevini daha verimli hale getirmektir. Listeyi oluşturan iki türü özetlemeye karar verdim, ancak boyut fonksiyonunun imzasını oluşturamıyorum. Prelude itibaren"Ya a b" türüyle nasıl eşleşiyorsunuz?

instance (Finite a, Finite b) => Finite (Either a b) where 
    elems = combineLists [Left x | x <- elems] [Right x | x <-elems] 
    size ??? = (size a) + (size b) 

, bunu Either a b = Left a | Right b biliyoruz.

Çalıştırdığım ilk şey, Either eşleşmesiydi, ancak tabi ki bu bir tür değil, bu yüzden çalışmıyor. Ardından, ((Left a) | (Right b))'u denedim, ancak bu konuda da devam etmeyeceğim. Başka hiçbir şey, Either a b türüyle eşleşiyor gibi görünüyor.

Ben derlemek için size (Left a) elde edebilir, ama b bileşeni eksik beri, hata alırsınız:

tabii bağlamında mantıklı
Ambiguous type variable `b' in the constraint: 
    `Finite b' arising from a use of `size' at <interactive>:1:0-12 

, ama gerçekten nasıl hiçbir ipucu var eşleşme Either a b.

Herhangi bir fikri olan var mı?

size (Left x) = size x 
size (Right x) = size x 

belirsiz tip değişkeni ilgili hata ayrı bir konudur: tip Either a b ait

+1

Bir tür ve yapıcı arasındaki fark hakkında biraz karıştı görünüyor. "Ya a b" iki Kurucular, "Sağ" "Sol" ve türüdür. Kurucular kod girerken, türler imzalara girer. türde bir çok "veri Foo = FON Int String" olarak, tip ve kurucu aynı adı kullandığından, bu ortak bir karışıklık olduğu; İlk "Foo" tür, ikincisi yapıcıdır. –

cevap

25

Bir şey ayrı olarak ele alınabilir iki olgu var bu yüzden, ya bir Left a veya Right b olduğunu. size (Left 1) gibi bir yorum yazarına girerseniz, sistem Left 1 değerinin "doğru" türünün ne olacağını anlayamaz. Either Int anything olabilir ve anything türünün ne olduğu bilinmediği sürece, Finite sınıfında olup olmadığı kontrol edilemez (size tarafından gereklidir).

Sen açık bir tip imzasını belirterek bu sorunu önleyebilirsiniz

:

rahatsız edebilir size için bir kukla argüman gerektiğini gibi görünüyor, ancak her iki tür a ve b için mankenleri geçemez
size (Left 1 :: Either Int String) 
0

tek bir Either a b. Belki her türde bir kukla olsun elems kullanabilirsiniz:

size _ = (size . head) (elems :: [a]) + (size . head) (elems :: [b]) 
0

Sana yaşıyorsanız çekirdek sorunu aynı anda diğer iki türlerinin her biri bir referans noktasını temsil eden bir tür istiyorum olduğunu düşünüyorum. Either a b, yalnızca bir tarihte a veya b'dan biri olabilir.

Aynı anda hem a hem de b'u temsil eden basit bir veri türü 2-tuple'dır.Böyle bir şey için tip imzası da bir tane oluşturmak için ifadesidir ve dolayısıyla desen birini Maching hangi (a, b) geçerli:

> :type (4,5) 
(4,5) :: (Num t, Num t1) => (t, t1) 
> let f (a, b) = 2*a + b 
> f (4,5) 
13 
Öyle gibi 2 başlığın ile ilk satırı yazmadan düşünmelisiniz

:

bu Finite (a, b) neyi temsil ediyor

instance (Finite a, Finite b) => Finite (a, b) where 
? Üye fonksiyon tanımları ne olurdu?

+0

Aslında ben zaten bunun tanımı yazdım, bir ve b'nin ürünü tüm b giden tarihiyle tüm yılların kurup olduğu – Fry

İlgili konular