Probablemente no le pueda dar a go
una firma de tipo como está.
La razón de esto es que hace uso de argumentos polimórficos vinculados por test
. Esto significa que, dentro de go
, el identificador f
tiene el tipo (ao -> ai)
para algunos tipos específicosao
y ai
.
variables de tipo son por lo general sólo en el alcance de la firma de tipo único en el que están introducidos, por lo que cuando usted da su tipo go
propia firma, el ao
y ai
de nuevas, tipos polimórficos, que por supuesto provoca un error de tipo cuando intente combinarlos con los tipos nombrados de manera similar, pero fijos (e incognoscibles) de la firma test
.
El resultado final es que no se puede escribir el tipo de go
explícitamente, lo cual no es muy satisfactorio. Para resolver esto, GHC ofrece the ScopedTypeVariables extension, que permite traer variables introducidas en una firma de tipo en el alcance dentro de la cláusula where
de la función, entre otras cosas.
Tenga en cuenta que si sólo utiliza la cláusula where
para crear un ámbito interno de las definiciones, y no hacer uso de identificadores vinculados por argumentos a la función externa, puede escribir las firmas de tipos en la cláusula where
igual que usted puede para enlaces de nivel superior. Si no desea usar las extensiones de GHC, simplemente puede pasar los parámetros de forma redundante. Algo como esto debería funcionar en ese caso:
test :: Monad m => (ao -> ai) -> Iteratee ai m b -> Iteratee ao m b
test f iter = go f $$ iter
where go :: Monad m => (ao -> ai) -> Step ai m b -> Iteratee ao m b
go f (Continue k) = continue $
\stream -> go f $$ k (fmap f stream)
go _ (Yield res _) = yield res EOF
@hammar: Gracias. Juro que hago un error tonto cada vez que coloco más de cuatro líneas de código en una respuesta sin cargarlas primero en GHCi. Suspiro... –