2012-09-09 30 views
6

Bu soruya, önceki soruma bağlı olarak yeni bir soru başlatarak başladım. Ben benzer kurucular oluşur iki veri türleri varsaVeri türlerini kullanma Haskell

: Eğer ben ne yapıyorum görebilirsiniz eğer

data A = C | Z 
data B = C 

data C = X | Y 

:

data A = X | Y | Z 
data B = X | Y 

olarak ben bir şekilde bu temsil edebilir yolu yoktur - Ben X | grup çalışıyorum Y bir veri türüne dönüştürülür, daha sonra diğer birçok veri türü tarafından kullanılabilir. Derleyicinin buna izin vermesi mümkün görünmüyor, ya da öyle görünüyorsa, X veya Y'ye göre eşleşme yapamıyorum, sadece C ??

C'nin birden çok kez bildirildiğini bildiren hata iletisini alıyorum.

Türlerimi kullanabileceğimi düşündüm, ancak birden çok yazımlamaya izin vermiyorlar.

I (aşağıda) gibi uzun bir yol beyan bile DÜZENLEME

, hala derlemek ve X ve Y birden bildirimleri var diyor olmaz: yapamayacağınız Sadece

data A = X | Y | Z 
data B = X | Y 
+0

Ne soruyorsun A 'bir alt türü olacağını '. Önceden var olan türlerden ayrılan yeni bir tür oluşturan "data" anahtar kelimesiyle bildirilmez. Haskell'in böyle bir özelliği olduğunu sanmıyorum, ancak tüm Haskell uzantıları ile kendimi özlüyorum. – Gilles

+0

@Gilles: Hayır, Haskell'in herhangi bir alt tipi polimorfizmi yok. Tip sınıfları üzerinden sadece parametrik polimorfizm ve ad-hoc polimorfizm vardır. Alabileceğiniz en yakın şey varoluşsal bir türdür, ama neredeyse değil, ama tamamen farklı bir şey. –

+0

Bunu bir cevap olarak koyardım, ama tam olmadığı için .. Bir yazımcım ilan ederek istediğin şeye daha yakınlaşabilirsin ve sonra o "ortak şeyler" için ihtiyaç duyduğun operasyonları yapabilirsin. Bu, bu sorunu çözmek için bir şeyler çevirmek için oldukça yaygın bir yoldur (bu versiyonun bir versiyonu). –

cevap

13

Bu, ilk seçeneğinizi de yapamazsınız - yani, aynı modülde X ve Y adında iki kurucuya sahip olamazsınız.

Bunu yapabiliyorsanız, X türünde C, A veya B mu? En belirgin cevap C olur, ancak A veya B'un gerekli olduğu bir bağlamda kullanamazsınız (Haskell'in hiçbir alt türü bulunmadığını unutmayın), böylece tüm yapının amacını yenecektir. Ya AC veya BC yapıcı türde bir değer yaratmak için

Sonra
data A = AC C | Z 
data B = BC C 
data C = X | Y 

Eğer bir C sarabilirdiniz:

yapabileceğiniz en iyi, A ve B'nin bir yapıcısındaki C sarmak için yani Sırasıyla A veya B.

+0

Sadece ilk seçeneğimin işe yaramadığını söyleyebilirim. "Sarmak" derken, "orijinal C'den ayırt etmek için C'nin önünde başka bir sözdizimi parçası" nu kastediyorsunuz? – Lethi

+2

@Dan Evet. Örneğimde, 'B' türünü oluşturmak için' A' ve 'BC X' türünde bir değer yaratmak için' AC X' yazacaksınız. X'in kendi başına iki farklı türü olamaz. – sepp2k

4

nedeni şöyle bu

data A = X | Y | Z 
data B = X | Y 

olduğunu yapamaz. İkinci yuvaya ilk yuvaya ve X içinde n oluşan bir çift oluşturur

foo n = (n,X) 

: Daha sonra bazı kod yazmak düşünelim. Derleyici hangi türden çıkar? X tip A bir yapıcı olduğundan geçerli bir tip

foo :: a -> A -> (a,A) 

olurdu, ama X tip B bir yapıcı olduğundan aynı derecede geçerli

foo :: a -> B -> (a,B) 

olduğunu.Aynı ada sahip iki kurucunuz varsa, bunları kullanan işlevler için benzersiz bir tür elde edemezsiniz. Aynı modüle aynı adla iki kurucu vermekten vazgeçtiniz.

1

Sen bunu yapamaz:

data A = C | Z 
data B = C 

data C = X | Y 

(Bu vesileyle, Bözdeş-C ise, o zaman neden hiç B var?)

Ama ne sen can böyle bir şey yap:

data A = A_Other C | Z 
data B = B_Other C 

data C = X | Y 

Sonra olabildiğince böyle desen maç: Birden veri Kurucular ilan olduğunuz için istediğini yapamaz

0

mantıklı olursa

foo :: A -> String 
foo (A_Other X) = "X" 
foo (A_Other Y) = "Y" 
foo (  Z) = "Z" 

bar :: B -> String 
bar (B_Other X) = "X" 
bar (B_Other Y) = "Y" 

foobar :: C -> String 
foobar X = "X" 
foobar Y = "Y" 

....

data A = X | Y | Z 

yılında Aslında 3 kurucular (değerler) X, Y ve Z sahiptir tip A tanıtıyoruz. Bu nedenle, ilk kod parçanız derlenmez, aynı adı iki farklı tür için kurucu olarak listelenir! Bunu olsaydı kendinizi

X :: A 

veya

X :: B 

olmayan bir nesne yönelimli bir bağlamda korkutucu

olduğunu sormalısınız! Bu nedenle, temel verileri, C paylaşmak için farklı kurucu adları sağlamanız gerekir. Eğer bu faktör istiyorsanız diğer mesajlar önerdi ve her veri türü için benzersiz kurucular çarpanlarına aşımı veri gibi

, yapabileceğiniz

data A = CForA C | Z 
data B = CForB C 

data C = X | Y