2012-06-17 10 views
5

Haskell'deki cebirsel DT'leri öğreniyorum. Benim yapmak istediğim, mevcut olanı "genişleten" yeni bir ADT yaratmak. İstediğimi nasıl ifade edeceğimi, bir alternatif örüntüyü özümseyebileceğini veya bir çözümü özebileceğini bulamıyorum. Farklı tipler olmasını istiyorum, ancak sadece yapıştırma ve yapıştırma aptalca bir çözüm gibi yapıştırarak. Aşağıdaki kod, aradığım şeyi en iyi açıklıyor.Haskell'in cebirsel veri tipleri: "pseudo-extend"

data Power = 
    Abkhazia | 
    -- A whole bunch of World powers and semi-powers 
    Transnistria 
    deriving (Eq, Show) 

data Country = 
    --Everything in Power | 
    Netural | 
    Water 
    deriving (Eq, Show) 

Düzenleme: Ben

let a = Abkhazia :: Country 

değil

let a = Power Abkhazia :: Country 
+1

Bunu yapmak için nedenler genellikle bir OO-y düşünce düşüncesinden geliyor ;-), ancak PowerCountry için bir Güç tutan Ülke içinde her zaman bir kurucu ekleyebilirdiniz. –

+0

Hmm Abhazya ve Transdinyester'in bir Haskell koduna nasıl geldiğini sorabilir miyim? Bu iki yerle nasıl bağlantılısınız? Bir çeşit oyun üzerinde mi çalışıyorsun? Hangi ülkedensin? –

+0

Abhazya ve Transdinyester http://en.wikipedia.org/wiki/List_of_sovereign_states Sadece Haskell öğrenme ve pratik bir fikir geldi am "Diğer devletler" listesinde ilk ve son bulunmaktadır. Sanırım bir oyun olabilir ama henüz niyetim yok. –

cevap

8

Buna gerek bu (GHCi olarak) yapabilmek istiyorum ... Biraz açıklamaya ihtiyacımız düşünüyorum

data Power 
     = Abkhazia 
     | Transnistria 
    deriving (Eq, Show) 

    data Country 
     = Powers Power -- holds values of type `Power` 
     | Netural  -- extended with other values. 
     | Water 
    deriving (Eq, Show) 

: bir ağaç olarak kendilerini temsil

Düzenleme: Bu soruna yönelik uzantınız bunu biraz daha basit hale getirir: Hem Ülke hem de Güç türleri, "ülkeler" olarak bazı yaygın davranışları paylaşır. Bu, veri türü için verilen ortak davranışlara Haskell açık, genişletilebilir tip sınıf türünü kullanmanızı önerir. Örneğin.

data Power = Abkhazia | Transistria 

    data Countries = Neutral | Water 

sonra, şeylerin Güç ve Ülkeler hem hisse için bir tür sınıfı:

class Countrylike a where 
     landarea :: a -> Int -- and other things country-like entities share 

    instance Countrylike Power where 
     landarea Abkhazia = 10 
     landarea Transistria = 20 

    instance Countrylike Countries where 
     landarea Neutral  = 50 
     landarea Water  = 0 

o zaman ya güçler ya da ülkeler üzerinde temiz bir şekilde landarea kullanabilirsiniz. Ve daha fazla örnek ekleyerek gelecekte yeni türlere genişletebilirsiniz.

+0

Bu neredeyse istediğim şey, ama açıklamaya bak. Teşekkürler! –

+1

@Raisdead bunu Haskell'de yapamazsınız, ve Don bilecek, ... (Ancak, alt türlemeyi simüle etmek için çokvarmetre tipi sınıflarını kullanabilirsiniz, bu ne demek istediğinizi gösterir. Her durumda, Don'un cevabı muhtemelen en iyisidir alacaksın ve ne kullanmalısın.) –

2
{-# LANGUAGE GADTs, StandaloneDeriving #-} 
data POWER 
data COUNTRY 

data CountryLike a where 
    Abkhazia :: CountryLike a 
    Transnistria :: CountryLike a 
    Netural :: CountryLike COUNTRY 
    Water :: CountryLike COUNTRY 

deriving instance Show (CountryLike a) 
deriving instance Eq (CountryLike a) 

type Power  = CountryLike POWER 
type Country = CountryLike COUNTRY 

foo :: Power 
foo = Abkhazia 

bar :: Country 
bar = Abkhazia 

baz :: Country 
baz = Netural 

Düzenleme: Alternatif type Power = forall a. CountryLike a olacaktır (Avantajı:. PowerCountry bir alt tipi Dezavantajı yapar: Bu örneğin Power -> Int can sıkıcı olma eğilimi daha yüksek rütbe türü vb (tip çıkarsama) yapacak)