2012-05-22 17 views
6

mam funkcję jak poniżej:funkcja nie mógł dopasować rodzaj

foo :: Int -> a -> [a] 
    foo n v = bar n 
     where 
     bar :: Int -> [a] 
     bar n = take n $ repeat v 

korzystając raport ghci ten błąd:

Couldn't match type `a' with `a1' 
      `a' is a rigid type variable bound by 
       the type signature for foo :: Int -> a -> [a] at hs99.hs:872:1 
      `a1' is a rigid type variable bound by 
       the type signature for bar :: Int -> [a1] at hs99.hs:875:9 
    Expected type: [a1] 
     Actual type: [a] 
    In the expression: take n $ repeat v 
    In an equation for `bar': bar n = take n $ repeat v 

Jeśli usunięcie deklaracji typu pręta, kod może zostać skompilowany bezbłędnie. Jaka jest tutaj właściwa deklaracja typu bar? I dlaczego pojawia się błąd, ponieważ deklaracja typu bar jest bardziej ogólna niż definicja paska (który jest związany z jakimś typem w foo)?

Dzięki za pomoc!

Odpowiedz

9

The a w

foo :: Int -> a -> [a] 

i a w

bar :: Int -> [a] 

różne zmienne typu o tej samej nazwie.

Aby uzyskać zachowanie można oczekiwać, włącz rozszerzenia ScopedTypeVariables (na przykład przez wstawienie {-# LANGUAGE ScopedTypeVariables #-} na początku pliku źródłowego) i zmień podpis typu dla foo do

foo :: forall a. Int -> a -> [a] 

Kiedy ScopedTypeVariables nie jest włączona, to tak jakby oryginalny kod został napisany tak:

foo :: forall a. Int -> a -> [a] 
foo n v = bar n 
    where 
    bar :: forall a. Int -> [a] 
    bar n = take n $ repeat v 

nie jest prawdą, że ghci implici tly używa ScopedTypeVariables, jeśli pominąć adnotację typu dla bar.

Zamiast tego adnotacja typu, którą podajesz dla bar, jest w konflikcie z typem ghci infers --- twierdzisz, że bar ma typ, który ghci wie, że nie może mieć.

Po usunięciu adnotacji typu usuwasz konflikt.

ScopedTypeVariables zmienia znaczenie adnotacji typu, które podajesz. Nie wpływa to na sposób wyświetlania typów ghc.

+0

Dzięki za pomoc! Jak już powiedziałem, jeśli usuwając deklarację typu "bar", ghci może skompilować kod, czy to znaczy, że ghci domyślnie używa tutaj ScopedTypeVariable? – Orup

+0

są bardziej przejrzyste, zmienne typu scoped i usuwając deklarację typu "bar", oba mogą spowodować kompilację kodu. tylko zastanawiam się, czy robią tę samą sztuczkę. – Orup

+0

Nie, dostają ten sam skompilowany kod, ale dostają się tam inaczej. Zobacz moją edycję. – dave4420

Powiązane problemy