2010-11-20 18 views
7

¿Cómo puede ser, que las siguientes comprobaciones de tipo¿Cómo funcionan exactamente los sinónimos de tipo?

{-# LANGUAGE RankNTypes #-} 
module Main where 

class Foo a where 


type FunFoo = (Foo a) => a -> IO() 

data Bar = Bar { 
    funFoo :: FunFoo 
} 

setFunFoo :: FunFoo -> Bar -> Bar 
setFunFoo action bar = bar {funFoo = action} 

pero cuando se cambia el tipo de firma fuera setFunFoo a

setFunFoo :: ((Foo a) => a -> IO()) -> Bar -> Bar 

no lo hace? ¿Hay alguna manera de expresar el código anterior sin el sinónimo tipo FunFoo?

+3

¿Está seguro de que pretendía utilizar los tipos rank-n? Es un tema bastante avanzado para alguien que pregunta cómo funcionan los sinónimos de tipo. –

Respuesta

7

es necesario agregar una explícita forall así:

setFunFoo :: (forall a. (Foo a) => a -> IO()) -> Bar -> Bar 

La razón de esto es porque desea que el ámbito de aplicación del tipo de variable a que se limita al tipo del primer argumento a setFunFoo. Sin el forall explícito, el tipo desajustado es este:

setFunFoo :: forall a. ((Foo a) => a -> IO()) -> Bar -> Bar 
Cuestiones relacionadas