2012-05-22 13 views
6

tengo la función de la siguiente manera:función no pudo igualar el tipo

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

usando ghci informe de este error:

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 

Si la eliminación de la declaración de tipo de barras, código puede ser compilado sin errores. Entonces, ¿cuál es la declaración de tipo de barra adecuada aquí? ¿Y por qué ocurre el error, porque la declaración de tipo de barra es más genérica que la definición de barra (que está vinculada a algún tipo en foo)?

¡Gracias por cualquier ayuda!

Respuesta

9

El a en

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

y la a en

bar :: Int -> [a] 

son diferentes variables de tipo con el mismo nombre.

Para obtener el comportamiento que espera, activar la extensión ScopedTypeVariables (por ejemplo, mediante la inserción de {-# LANGUAGE ScopedTypeVariables #-} en la parte superior de su archivo de origen), y cambiar la firma tipo de foo a

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

Cuando ScopedTypeVariables no está habilitado, es como si su código original fue escrito así:

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

no es cierto que ghci implici tly usa ScopedTypeVariables si omite la anotación de tipo para bar.

En su lugar, la anotación tipo que da para bar entra en conflicto con el tipo ghci infers --- usted afirma bar tiene un tipo que ghci sabe que no puede tener.

Al eliminar la anotación de tipo, elimina el conflicto.

ScopedTypeVariables cambia el significado del tipo de anotaciones que proporciona. No afecta cómo ghc infiere los tipos.

+0

Gracias por la ayuda! Como dije, si elimina la declaración de tipo de 'barra', ghci puede compilar el código, ¿eso significa que ghci usa implícitamente ScopedTypeVariable aquí para ello? – Orup

+0

ser más claras, las variables de tipo de ámbito y eliminar la declaración de tipo 'bar' pueden hacer que el código se compile. Me pregunto si están haciendo el mismo truco. – Orup

+0

No, obtienen el mismo código compilado, pero llegan de forma diferente. Ver mi edición – dave4420

Cuestiones relacionadas