2012-05-22 26 views
6

Ich habe Funktion wie folgt:Funktion konnte nicht Typ entsprechen

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

mit GHCI Bericht diesen Fehler:

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 

Wenn die Typdeklaration von Bar zu entfernen, Code ohne Fehler kompiliert werden. Also, was ist die richtige Typ-Deklaration von bar hier? Und warum tritt ein Fehler auf, weil die Typdeklaration von bar generischer ist als die Definition von bar (die an einen Typ in foo gebunden ist)?

Danke für jede Hilfe!

Antwort

9

Die a in

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

und die a in

bar :: Int -> [a] 

sind verschiedene Arten Variablen mit dem gleichen Namen.

das Verhalten bekommen Sie erwarten, schalten Sie die ScopedTypeVariables Erweiterung (zB durch {-# LANGUAGE ScopedTypeVariables #-} an der Spitze der Quelldatei einfügen), und die Art Signatur von foo zu

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

Wenn ScopedTypeVariables ändern

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

es ist nicht richtig zu sagen, dass GHCI implici: nicht aktiviert ist, wird es, als ob Ihr ursprünglicher Code wurde so geschrieben tally verwendet ScopedTypeVariables, wenn Sie den Typ Annotation für bar weglassen.

Stattdessen die Art Annotation, die Sie für bar geben Konflikte mit dem Typ ghci infers --- Sie behaupten, bar hat einen Typ, den Ghci weiß es nicht haben kann.

Wenn Sie den Typ Annotation entfernen, entfernen Sie den Konflikt.

ScopedTypeVariables ändert die Bedeutung von Typanmerkungen, die Sie angeben. Es wirkt sich nicht darauf aus, wie ghc Typen leitet.

+0

Dank für die Hilfe! Wie gesagt, wenn ghci die Typdeklaration von 'bar' entfernt, kann der Code kompiliert werden. Bedeutet das, dass ghci hier implizit ScopedTypeVariable verwendet? – Orup

+0

klarer sein, Bereichsvariablen und Entfernen von 'bar' Typ-Deklaration beide können den Code kompiliert werden. Ich frage mich nur, ob sie den gleichen Trick machen. – Orup

+0

Nein, sie bekommen den gleichen kompilierten Code, aber sie kommen anders dort hin. Siehe meine Bearbeitung. – dave4420

Verwandte Themen