2016-04-08 14 views
0

Türü sabit değeri almak için undefined kullanmaya çalışıyorum (sizeOf gibi bir şey saklanabilir). Ben sınırdır a tipi değişken olarak açıkça typeConst argüman için türünü belirtilen dikkateÖrnek beyan örneğinde belirtildiği gibi

Could not deduce (MyClass a0) arising from a use of ‘typeConst’ 
from the context (Read a, MyClass a) 
    bound by the instance declaration at src/Main.hs:13:10-49 
The type variable ‘a0’ is ambiguous 
Note: there is a potential instance available: 
    instance MyClass Int -- Defined at src/Main.hs:20:10 
In the second argument of ‘($)’, namely 
    ‘typeConst (undefined :: a)’ 
In the expression: length $ typeConst (undefined :: a) 
In an equation for ‘len’: len = length $ typeConst (undefined :: a) 

Ben orada tipi deducing sorun nedir anlamıyorum: Ancak

module Main where 

class MyClass a where 
    typeConst :: a -> String 
    --^Argument is ignored 

class TryRead a where 
    tryRead :: String -> Maybe a 

newtype ByLen a = ByLen a 

-- | Make all types under ByLen readable, if their typeConst's are longer then 3 characters 
instance (Read a, MyClass a) => TryRead (ByLen a) where 
    tryRead = if len > 3 
       then Just . ByLen . read 
       else const Nothing 
     where 
     len = length $ typeConst (undefined :: a) 

instance MyClass Int where 
    typeConst = const "moreThan3" 

main :: IO() 
main = go (tryRead "214234" :: Maybe (ByLen Int)) 
    where 
    go Nothing = print "Nothing :(" 
    go (Just (ByLen i)) = print i 

, bu hata veriyor MyClass a tarafından, bu yüzden benim aklımda typeConst işlevini uygulamak için hiçbir sorun olmamalıdır.

{-# LANGUAGE ScopedTypeVariables #-} 

bir sınıf örneğine içinde kullanılan, hiçbir şey özel ihtiyaçlar: Sen ScopedTypeVaribales uzantısına ihtiyacınız

+9

"ScopedTypeVariables" uzantısını kullanmanız gerekir: aksi halde, '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ile aynı olanı değil, daha yeni bir tür değişkeni (yani 'a0' vs . – gallais

+0

@gallais Teşekkürler, bu işe yarıyor. Şimdi birisinin cevap olarak yazmasını bekliyorum. Ama ben bu uzantı hakkında bir şeyler okudum ve şimdi anlamıyorum, neden açık bir şekilde forall olmadan çalışıyor? (Sınıf dışı bir işlevin içinde böyle bir şey denedim ve bunu bir "forall" ekleyene kadar derlemedim.) – Cthulhu

+0

Tahminim, bir örnek bildirimin özel bir durum olduğu anlamına gelir: örneğini forall olarak bildirirseniz a. (...) => MyClass (Belki a) 'örneğin, örneğin bir 'Malformed instance' hatası alırsınız. – gallais

cevap

1

dosyasının en üstünde bir ghc bayrak -XScopedTypeVariables içinden veya pragma yoluyla ya bu iş için etkinleştirilmesi yapılacaktır, çünkü sınıfın başındaki tip değişkenleri zaten kapsam dahilindedir, ancak basit üst düzey işlevde kullanmak isterseniz, tip imzasında açık bir forall olması gerekir.

İlgili konular