Hola,
La idea es que a partir del tipo de curry, uncurry y flip,
curry :: ((a,b) -> c) -> (a -> b -> c)
uncurry :: (a -> b -> c) -> ((a,b) -> c)
flip :: (a -> b -> c) -> (b -> a -> c)
se determine el tipo de cada una de esas expresiones.
La idea es que a partir del tipo de curry, uncurry y flip,
curry :: ((a,b) -> c) -> (a -> b -> c)
uncurry :: (a -> b -> c) -> ((a,b) -> c)
flip :: (a -> b -> c) -> (b -> a -> c)
se determine el tipo de cada una de esas expresiones.
Por ejemplo, en la respuesta (a), uncurry se está aplicando a la función flip. En ese caso es flip quien está jugando el rol de la función currificada a la cual se le aplica uncurry. Para ello, el tipo de flip se puede ver equivalentemente como:
flip :: (a' -> b' -> c') -> b' -> a' -> c'
en donde renombré las variables de tipo a, b , y c como a', b' y c', y saqué los paréntesis, dado que la flecha (->) asocia a la derecha (por lo que los paréntesis no son necesarios). Por lo tanto, uncurry ve a flip como la función currificada de tipo (a -> b -> c) que toma como entrada, donde en el caso de flip a = a' -> b' -> c', b = b', y c = a' -> c'. Por lo tanto, uncurry flip da como salida una función no currificada de tipo ((a,b) -> c), que usando las igualdades de arriba dan:
uncurry flip :: (a' -> b' -> c', b') -> a' -> c'
Los otros casos son similares.
Saludos,
Alberto.
flip :: (a' -> b' -> c') -> b' -> a' -> c'
en donde renombré las variables de tipo a, b , y c como a', b' y c', y saqué los paréntesis, dado que la flecha (->) asocia a la derecha (por lo que los paréntesis no son necesarios). Por lo tanto, uncurry ve a flip como la función currificada de tipo (a -> b -> c) que toma como entrada, donde en el caso de flip a = a' -> b' -> c', b = b', y c = a' -> c'. Por lo tanto, uncurry flip da como salida una función no currificada de tipo ((a,b) -> c), que usando las igualdades de arriba dan:
uncurry flip :: (a' -> b' -> c', b') -> a' -> c'
Los otros casos son similares.
Saludos,
Alberto.