Supongamos que tengo un tipo de datos compuesto -Una "verdadera" función genérica en Haskell
data M o = M (String,o)
Ahora, puedo definir una función que funcione para todos, independientemente de M
o
. Por ejemplo -
f :: M o -> M o
f (M (s,o)) = M (s++"!", o)
Sin embargo, f
en realidad no es tan general como me gustaría que fuera. En particular, el uso de f
en una expresión fija el tipo de o
así que no puedo utilizar f
de nuevo con un tipo diferente de o
. Por ejemplo, la siguiente no se typecheck -
p f = undefined where
m1 = M ("1",())
m2 = M ("2", True)
m1' = f m1
m2' = f m2
Se produce el error - Couldn't match expected type 'Bool' with actual type '()'
Sorprendentemente, si no proporciono f como argumento y en su lugar simplemente uso la definición global de f entonces se compila y ¡funciona bien! es decir, esta compila -
p = undefined where
m1 = M ("1",())
m2 = M ("2", True)
m1' = f m1
m2' = f m2
¿Hay alguna razón en particular para esto? ¿Cómo puedo solucionar este problema es decir, definir una función f
que se puede aplicar a todos (M o)
, incluso cuando el o
varía dentro de la misma expresión? Supongo que existen tipos existenciales aquí, pero no puedo entender cómo.
Por qué le haría M un par de valores? Qué feo. – alternative
algo es "forall" por defecto, algo más no lo es. Puede ver estos textos: http://en.wikibooks.org/wiki/Haskell/Existenntially_quantified_types – Nybble
@monadic, es realmente solo un ejemplo mínimo que reproduce el problema al que me enfrentaba en mi código real (que es significativamente más complicado). –