2012-05-22 22 views
6

ho funzione come di seguito:funzione non poteva competere tipo

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

usando rapporto ghci questo errore:

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 

Se la rimozione della dichiarazione del tipo di barre, il codice può essere compilato senza errori. Quindi qual è la dichiarazione di tipo corretta di bar qui? E perché l'errore si verifica, perché la dichiarazione del tipo di barra è più generica della definizione di barra (che è associata ad un tipo in foo)?

Grazie per qualsiasi aiuto!

risposta

9

Il a in

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

e a in

bar :: Int -> [a] 

sono diverse variabili di tipo con lo stesso nome.

Per ottenere il comportamento che ci si aspetta, attivare l'estensione ScopedTypeVariables (ad esempio inserendo {-# LANGUAGE ScopedTypeVariables #-} nella parte superiore del file di origine), e cambiare la firma tipo di foo per

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

Quando ScopedTypeVariables non è abilitato, è come se il codice originale è stato scritto in questo modo:

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

non è vero che ghci implici tly utilizza ScopedTypeVariables se si omette l'annotazione del tipo per bar.

Invece, l'annotazione del tipo che si dà per bar è in conflitto con il tipo ghci - si sta affermando che bar ha un tipo che ghci sa che non può avere.

Quando si rimuove l'annotazione del tipo, si rimuove il conflitto.

ScopedTypeVariables modifica il significato delle annotazioni di tipo fornite dall'utente. Non ha alcun effetto su come i tipi di dati ghc.

+0

Grazie per l'aiuto! Come ho detto, se si rimuove la dichiarazione di tipo 'bar', ghci può compilare il codice, significa ghci implicitamente utilizzando ScopedTypeVariable qui per esso? – Orup

+0

essere più chiari, le variabili di tipo scoped e la rimozione della dichiarazione del tipo 'bar' entrambi possono rendere il codice compilato. mi chiedo solo se stiano facendo lo stesso trucco. – Orup

+0

No, arrivano allo stesso codice compilato, ma ci arrivano in modo diverso. Vedi la mia modifica. – dave4420

Problemi correlati