Variable tipo rígido — ¿por qué no aparece ningún error?
En el siguiente ejemplo, estoy implementando internamente la función f
. Su firma utiliza a
como si la variable de tipo a
estuviera englobada, y está funcionando sin darme un error de compilación a pesar de que no he habilitado la extensión ScopedTypeVariables
:
foo :: Int -> [a] -> [a]
foo n list = snd $ foldl f (1,[]) list where
f :: (Int,[a]) -> a -> (Int,[a])
f (k,l) r
| k==n = (1,l++[r])
| otherwise = (k+1,l)
Esperaba el error: "No se puede hacer coincidir el tipo 'a1' con 'a' ..."
porque, como dije, estaba tratando la variable de tipo a
como si estuviera englobada aunque no está englobada.
Sé lo que es un tipo rígido y ya sé por qué aparece el error. Mi pregunta es por qué no obtengo el error aquí.
davy.ai
La razón por la que no recibes un error en este caso es porque la implementación de
f
está utilizando la variable de tipoa
que ya ha sido declarada en la firma de tipo defoo
. Esto significa que la variable de tipoa
está en alcance y disponible para ser utilizada en la implementación def
.Aunque
ScopedTypeVariables
no está habilitado, el alcance dea
sigue siendo limitado a la firma de tipo defoo
. Por lo tanto, el compilador es capaz de inferir que ela
utilizado en la implementación def
es la misma variable de tipo que ela
utilizado en la firma de tipo defoo
.Es importante tener en cuenta que este comportamiento puede no siempre funcionar como se espera, especialmente en situaciones de tipo más complejas. Por eso, habilitar la extensión
ScopedTypeVariables
puede ser útil en casos en los que se desea asegurar que una variable de tipo se utilice de manera consistente en toda la implementación de una función.