2014-10-29 7 views
8

Üzgünüm, çok önde okuyunuz, soru için daha iyi bir başlık hayal değil.Kapalı tip aileleri ve garip fonksiyon tipleri

doMagic :: a -> Family a 
doMagic = undefined 

exampleA = doMagic $ Just() 
exampleB = doMagic $() 

GHCi onunla oynamak: Hatta bu tip ailesini kullanarak bir işlev ilan edebilir

type family Family x where 
    Family (Maybe x) = Maybe x 
    Family x = Maybe x 

: Biz kendilerini Belkiler dışında kendisine her tip Maybe tekabül ediyor eşleştiren bir kapalı tip aileye sahip olduğunu düşünün fonksiyon uygulamanın türünü değerlendirmek Tamam olduğunu göstermektedir: herhangi implementati sağlamak mümkün olup olmadığını

*Strange> :t exampleA  
exampleA :: Maybe()  
*Strange> :t exampleB  
exampleB :: Maybe()  

sorudur undefined dışında doMagic işlevinin üzerinde? Örneğin, her değeri Just yapıcısına sarmak istediğimi söyleyeyim, Maybes hariç, sağlam kalmalıyım, bunu nasıl yapabilirim? Türlerini kullanmayı denedim, ancak kapalı tip aileleri kullanmıyorken doMagic işlevi için derlenebilir bir imza yazamadım, birisi bana yardım edebilir mi?

+1

doMagic x = Sadece undefined' da türlerini saygı dinamik yazılan dilin 'in. Teorik olarak, bir tip sistem buna izin verebilir (ama bu gerçekten faydalı olabilir mi?). BTW, betimlediğiniz örnek, hangi a tipi 'a' türüne bağlı olarak farklı şeyler yaparsanız, çalışma zamanında tür bilgisi isterken, Haskell tip silme işlemine izin verecek şekilde tasarlanmıştır (çalışma zamanında herhangi bir tip bilgisi yoktur). Yine de, bir tür sınıfı kullanarak yakın bir şey elde edebilirsiniz. – chi

+1

Dahası, soru "kapalı tip ailelerin varlığında bir türün _free teoremi nedir?" Ile ilgili görünüyor. – chi

cevap

8

Sen x den Maybe x ayırt etmek başka kapalı tip ailesini kullanabilir ve daha sonra bu iki durum için doMagic ayrı uygulamaları sağlamak için başka typeclass kullanabilirsiniz.Hızlı ve kirli versiyon:

{-# LANGUAGE TypeFamilies, MultiParamTypeClasses, 
    FlexibleInstances, UndecidableInstances, ScopedTypeVariables #-} 

type family Family x where 
    Family (Maybe x) = Maybe x 
    Family x = Maybe x 

data True 
data False 

type family IsMaybe x where 
    IsMaybe (Maybe x) = True 
    IsMaybe x = False 


class DoMagic a where 
    doMagic :: a -> Family a 

instance (DoMagic' (IsMaybe a) a (Family a)) => DoMagic a where 
    doMagic = doMagic' (undefined :: IsMaybe a) 


class DoMagic' i a r where 
    doMagic' :: i -> a -> r 

instance DoMagic' True (Maybe a) (Maybe a) where 
    doMagic' _ = id 

instance DoMagic' False a (Maybe a) where 
    doMagic' _ = Just 


exampleA = doMagic $ Just() 
exampleB = doMagic $() 
+0

Bu oldukça şaşırtıcı. – dfeuer

4

Sen çeşit boyunca hobbles bir doMagic fonksiyonunu yapabilirsiniz. Ne yazık ki, tip ailesinin kapalı olması gerçekten size çok yardımcı olmuyor.

*Main> doMagic $ Just() 
Just() 
*Main> doMagic $() 
Just() 

Öyleyse neden o boyunca hobbling oluyor dersiniz: Burada başlangıç ​​

{-# LANGUAGE TypeFamilies #-} 

type family Family x where 
    Family (Maybe x) = Maybe x 
    Family x = Maybe x 

class Magical a where doMagic :: a -> Family a 
instance Magical (Maybe a) where doMagic = id 
instance Magical() where doMagic = Just 

Sen İstediğiniz gibi GHCi çalışan görebilirsiniz görünebilir nasıl? İkiniz sağlanan örnekleri tiplerinin Haskell ekosistemin çok örtmeyen fark etmiş olabilirsiniz:

*Main> doMagic $ True 
<interactive>:3:1: 
    No instance for (Magical Bool) arising from a use of ‘doMagic’ 
    In the expression: doMagic 
    In the expression: doMagic $ True 
    In an equation for ‘it’: it = doMagic $ True 

Yani bir ilgi her tür (kurucu) için örneklerini sağlamak zorunda olacaktır. Gerçekten de, tutarsız örneklerin bile - ki bu tür sorunların çoğu kez gönderilebileceği kulüp - burada yardımcı olur; tek yazmaya çalışırsa

instance Magical (Maybe a) where doMagic = id 
instance Magical a where doMagic = Just 

derleyici haklı sonuçta tam olarak polimorfik örneği aslında doğru türde olan bilmediklerini şikayet ediyor. Tutarsız örneklerle ilgili olan şey, derleyici tarafından söylenmemesidir, çünkü bu sadece seçilen örnekte olduğu için, diğer örneklerin kesinlikle 'un uygulamamasıdır. Bu yüzden tam olarak polimorfik bir örneği seçmemiz mümkün, ancak daha sonra sahnelerin arkasında gerçekten bir Maybe olduğumuzu keşfettik ve daha sonra bir çok şeyi Maybe etrafına sardık. Talihsiz.

Şu anda bu konuda yapılabilecek çok fazla şey yok. Kapalı tip aileler şu anda mevcut olabilecek tüm bilgileri sağlamazlar. Belki bir gün GHC, kapalı tip aileleri bu tür bir eşitsizlik kısıtlaması gibi daha kullanışlı hale getiren bir mekanizma sunacak, ancak nefesimi tutamayacağım: bu yararlı bilgiyi nasıl sağlayacağına dair bir araştırma problemi ve Bunu yapan insanların söylentilerini duydum.