2012-07-16 10 views
8

Burada toplam acemi, mücadele.Haskell: Setler için bir tip sınıfını nasıl tanımlayabilirim?

Setler için bir tip sınıfı tanımlamaya çalışıyorum. Bu durumda sadece 'var olan' tanımını gerektirirdi. 'var', set edilmiş bir öğe üzerinde bir set ve fonksiyon alır ve bir boolean döndürür. Bunu Haskell'de nasıl tanımlayabilirim?

Aşağıdakiler doğru yönde mi? sınıf için Çok fazla parametre `ayarlayın:

(sonuç - Yani tipi sınıf tanımı ve 'var' şimdilik doğrudur döndürdüğü listesiyle setin bir uygulanması ..

-- Set.hs -- 

class Set a b where 

    exists :: a -> (b -> Bool) -> Bool 


-- ListSet.hs -- 

instance Set ListSet a where 

    exists a f = True 

var ')

cevap

13

Bu şekilde, yeterli uzantılarla yapabilirsiniz. En azından çok parametreli tip sınıflarına ihtiyacınız olacak. Ancak, kullanmak çok can sıkıcı olacaktır: her yerde açık tip imzaları belirtmeniz gerekir. de

class Set a b | a -> b where 
    exists :: a -> (b -> Bool) -> Bool 

Bu setin türünü biliyorsanız, elementlerin türünü bilmek söylüyor: bunu düzeltmek için bir yolu (başka uzantısı kullanarak) işlevsel bağımlılığını tanıtmaktır. İşte

class Set f where 
    exists :: f a -> (a -> Bool) -> Bool 

, tip sınıfı yüksek kinded türleri üzerinde aralıkları, düzgün bir hile ve zor asla ettik eğer kendi başınıza ile gelip: Ancak, herhangi bir uzantıları olmadan çalışan daha basit bir yolu var daha önce gördüm!

+1

Tabii ki, ikincisi, eleman tipinin set tipine son tip parametresi olmasını gerektirir - a -> Bool' için bir örnek oluşturmak istiyorsanız, her zaman mümkün olmayan bir şey. İlişkili tip aileler ise, bunu iyi bir şekilde çözer. – Carl

+2

Teşekkürler! İkinci yol çalışıyorum! Orada neler olup bittiğini tam olarak anlayamadığımı itiraf etmeliyim ama umarım bana kendini gösterir ... – tero

7

Daniel Wagner zaten ne yapmaya çalıştığınıza dair mükemmel bir cevap verdi. Sadece senin hatan hakkında bir nokta eklemek istiyorum - Too many parameters for class 'Set'. Bu, ilgili GHC uzantısını etkinleştirmediğiniz anlamına gelir - MultiParamTypeClasses. Eğer kaynak dosyasının en üstünde yorumun özel bir tür belirterek yapabilirsiniz:

{-# LANGUAGE MultiParamTypeClasses #-} 
-- 
-- Your source code here 
-- 

Sonra kodunuzu derlemek mümkün olmalıdır.

Daniel'in cevabında sözü edilen başka bir Haskell özelliği, belirli uzantıyı etkinleştirmeyi de gerektirir, yani FunctionalDependencies (bu, tip sınıf bildiriminde garip .. | a -> b .. şeydir). Böyle, virgül kullanarak aynı anda birden fazla uzantıları etkinleştirebilirsiniz:

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-} 

Carl'ın açıklama ayrıca (kümesi türleri veya diğer jenerik sınıfını yapmaya çalışıyoruz ne için araç olabilecek başka uzantısı, TypeFamilies, bahseder tür koleksiyonlar). Burada okuyabilirsiniz: http://www.haskell.org/haskellwiki/Type_families.

+0

Bunu da işlevsel bağımlılık yöntemiyle yapmayı başardım. Bununla birlikte, 'FlexibleInstances' uzantısını da eklemeliydim. – tero