2015-09-17 19 views
7

Bu yükleri: ilehatasız

data Const c a = Const c 

instance Functor (Const c) where 
    fmap _ (Const v) = Const v 
... ama bu

data Const' c a = Const' c 

instance Functor (Const' c) where 
    fmap _ cv = cv 

... başarısız hata. Derleyici neden cv türünün Const' c türüne dönüştürebiliyor? Beyanın geri kalanı ve fmap'un tanımı göz önüne alındığında başka ne olabilir?

+3

Neyse ki, 'Const' kurucusunu çıkarmak ve onu geri koymak ücretsizdir, çünkü Const 'yeni bir türdür. Durum, "Her ikisi" için çok üzücüdür; burada, temsil aynı kalsa bile, türü değiştirmek için belleğin ayrılması gerekebilir. – dfeuer

cevap

9

, bir lokma biraz olan

{-# LANGUAGE ScopedTypeVariables, InstanceSigs #-} 

data Const c a = Const c 

instance Functor (Const c) where 
    fmap :: forall a b. (a -> b) -> Const c a -> Const c b 
    fmap _ (Const v :: Const c a) = Const v :: Const c b 

yazabilir. :-)

forall a b., a ve b'u kapsam içine getirerek tanımda belirtilebilir. Bu, ScopedTypeVariables tarafından etkinleştirilmiştir. InstanceSigs, ilk etapta fmap imzasını yazmamıza izin verir (normalde , sınıfından çıkarılmalıdır, bu yüzden tür değişken adlarını almak için hiçbir yerimiz yoktur).

+2

Orada 'c' sayısallaştırılmalıdır emin misin?Bana öyle geliyor ki, 'c' örnek başlığın örtülü olarak bağlı olması gerekir. – pyon

+2

Haklısınız. Son dakikada c ölçtüm ama yanlış. Sabit – luqui

+0

Tekrar teşekkürler. Şimdi kristal berraklığında. – kjo

7

cv, Const' c a türünde olduğu için Const' c b türünde de olamaz (a ~ b değilse). Bununla birlikte, Const v ve Const v, farklı tiplerde olabilir.

bakarak bir başka yolu fmap _ cv = cv tip Const' c a -> Const' c a olacağını fmap _ = id, denk olduğunu, ancak fmap _ tip Const' c a -> Const' c b olmalıdır. tam açık olmasını istiyorsanız

+1

Buna bakmanın başka bir yolu, haskell sözdiziminin, tip parametrelerini örtük hale getirmesi ve bunları bağlamdan ayırmasıdır. Tanımın tam şekli, 'fmap _ (Const {c a} v) = Const {c b} v' (burada' {} ', tip uygulamasını gösterir), denklemin iki tarafının farklı olduğunu açıkça ortaya koyar. – luqui

+0

@luqui: Derleyicinin kabul edeceği tanımın tam formunu yazmanın bir yolu var mı? Gösterdiğin çeşitli varyantları denedim, ancak derleyici hepsini reddediyor. – kjo

+0

@kjo Luqui'nin gösterdiği şey gerçek sözdizimi değil. Bunu Haskell programlarında kullanamazsınız. –

İlgili konular