2013-05-03 16 views
8

Haskell'de, bir veri tipini bileşenlerinin değeriyle sınırlamanın bir yolu var mı? Bir örnek hazırladım. Dama oyununun olduğunu söyle. Bir denetleyici, Siyah veya Beyaz türündendir.Can Haskell Veri Beyannameleri Tip Değerlere Göre Sınırlandırılıyor

data CheckerType = BlackChecker | WhiteChecker deriving (Eq) 

data Checker = Checker CheckerType Int 

Bir dama oyunu için oyun tahtası Siyah dama ve Beyaz dama bir dizi içerir.

Önceki açıklamada
data GameBoard = GameBoard ([Checker]) ([Checker]) 

, CheckerType olması kriteri: [Denetleyicisi] içinde dama uygulamak için herhangi bir yolu, rakip tipte siyah ve ikinci var mı? Bunlardan hiçbiri herhangi bir değer olduğunu

data Black 
data White 

Not:

+0

olası yinelenen [pozitif tamsayı türü] (http://stackoverflow.com/questions/11910143/positive-integer-type) – dave4420

cevap

13

benzer bir şey yapmanın en kolay yolu, bir "hayalet türü" denen bir Checker tip parameterize etmektir. Sadece Checker'un hangi renk olduğunu belirtmek için varlar.

arada
data Checker a = Checker Int 

data GameBoard = GameBoard [Checker Black] [Checker White] 

, sen GameBoard bildiriminde bu parantez gerekmez.

Bu yaklaşımın olumsuz tarafı, iki rengin artık farklı türlerde olmasıdır, yani, birden fazla rengin damalarını, sadece tek bir rengi içeren bir işlev yazamazsınız.

data Black = Black 
data White = White 

data Checker a = Checker a Int 

type AnyChecker = Checker (Either Black White) 

Ama bu hızla sorunsuz bir çok kullanmak olabilir:

İzin verilen renkleri izlemek amacıyla biraz daha somut fantom türlerini yapabiliriz.

Gerçekten istediğinizden şüphelendiğim, tüm bağlamlarda tamamen farklı bir tür yapmadan bir bağlamda izin verilen değerler aralığını kısıtlamanın bir yoludur. Ne yazık ki, bu Haskell'deki herhangi bir basit şekilde mümkün değildir.

Bu makul bir fikir ve bazı diller benzer özelliklere sahip. Böyle genel bir yolla bu gibi destekleyici ayrımlar, Haskell'in mevcut tipte sisteme, zarar görmeden zarar vermeksizin, bu tür bir özelliği kullanmayan kodlarda bile, daha az sağlam, tür çıkarımı yapmak gibi basit bir yöntem değildir.

+7

Bunu yapmak istemezseniz, bir geçici çözüm orijinal kodunuzla uyumlu olabilir ama 'GameBoard' yapıcısını dışa aktarmayın. Bunun yerine, modülünüzün kullanıcıları, denetleyicileri uygun şekilde ayıran özel bir yapıcıyı çağırmaya ve renk ayırmalarını koruyan işlevleri kullanarak güncelleştirmeye zorlar. – mhwombat