Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

281
Vistas
¿Cómo implementar la notación do monádica usando un Coroutine?

Traduje la implementación de coroutine de Control.Monad.Coroutine a Javascript. La traducción puede contener algunos errores, pero mi problema real es que no sé cómo poner todo junto para aplicarlo.

El tipo de rutina sin procesar es m (Either (s (Coroutine smr)) r) , donde m tiene una mónada y s una restricción de funtor:

 -- | Suspending, resumable monadic computations. newtype Coroutine smr = Coroutine { -- | Run the next step of a `Coroutine` computation. -- The result of the step execution will be either a suspension or -- the final coroutine result. resume :: m (Either (s (Coroutine smr)) r) } instance (Functor s, Monad m) => Monad (Coroutine sm) where ....

Aquí está la traducción:

 const TAG = Symbol.toStringTag; const CoroutineT = mmx => ({ [TAG]: "Coroutine", run: mmx }); CoroutineT.map = ({map: mapSuspension}, {map: mapBase}) => f => function go(mmx) { return CoroutineT(mapBase(mx => mx.run({ left: tx => Either.Left(mapSuspension(go) (tx)), right: x => Either.Right(f(x)) })) (mmx.run)); }; CoroutineT.ap = ({map: mapSuspension}, {map: mapBase, chain}) => function go(mmf) { return mmx => CoroutineT(chain(mmf.run) (mf => mx.run({ left: tf => Either.Left(mapSuspension(go) (tf)), right: f => mapBase(mx => mx.run({ left: tx => Either.Left(mapSuspension(go) (tx)) right: x => Either.Right(f(x)) })) (mmx.run) }))); }; CoroutineT.of = ({of}) => x => CoroutineT(of(Either.Right(x))); CoroutineT.chain = ({map}, {of, chain}) => mmx => fmm => function go(mmx2) { return CoroutineT(chain(mmx2.run) (mx => mx.run({ left: tx => of(Either.Left(map(go) (tx))), right: x => fmm(x).run }))); } (mmx); // transformer CoroutineT.lift = ({map}) => comp(CoroutineT) (map(Either.Right)); CoroutineT.mapT = ({map: mapSuspension}, {map: mapBase}) => f => function go(mmx) { return CoroutineT( mapBase(mx => mx.run({ left: tx => Either.Left(mapSuspension(go) (tx)), right: x => Either.Right(x) })) (f(mmx.run))); }; CoroutineT.consume = ({of, chain}) => f => mmx => CoroutineT(chain(mmx.run) (mx => mx.run({ left: tx => f(tx) right: x => of(Either.Right(x)) }))); CoroutineT.exhaust = ({of, chain}) => f => function go(mmx) { return chain(mmx.run) (mx => mx.run({ left: tx => go(f(tx)), right: of })); }; CoroutineT.exhaustM = ({of, chain}) => fm => function go(mmx) { return chain(mmx.run) (mx => mx.run({ left: tx => chain(fm(x)) (go), right: of })) }; CoroutineT.fold = ({of, chain}) => f => init => mmx => function go([acc, mmx2]) { return chain(mmx2.run) (mx => mx.run({ left: tx => go(f(acc) (tx)), right: x => of(Pair(acc, x)) })); } (Pair(init, mmx)); // suspension functor CoroutineT.mapSuspension = ({map: mapSuspension2}, {map: mapBase}) => f => function go(mmx) { return CoroutineT( mapBase(mx => mx.run({ left: tx => Either.Left(f(mapSuspension2(go) (tx))), right: x => Either.Right(x) })) (mmx.run)); }; CoroutineT.suspend = ({of}) => tx => CoroutineT(of(Either.Left(tx))); // Yield suspension export const Yield = x => y => ({ [TAG]: "Yield", run: Pair(x, y) }); Yield.map = f => tx => Yield(tx[0]) (f(tx[1])); Yield.yield = ({of}) => x => CoroutineT.suspend({of}) (Yield(x) (of(null))); // Either const Either = {}; Either.Left = x => ({ [TAG]: "Either", run: ({left}) => left(x) }); Either.Right = x => ({ [TAG]: "Either", run: ({right}) => right(x) }); Either.cata = left => right => tx => tx.run({left, right});

Las corrutinas son una generalización de los generadores, por lo que implementar la siguiente función similar a la notación parece consistente (aunque estamos atascados con el anidamiento nuevamente):

 const _do = ({chain, of}) => init => gtor => { const go = ({done, value: mx}) => done ? mx : chain(mx) (x => go(it.next(x))); const it = gtor(init); return go(it.next()); }; const of = x => [x]; const chain = xs => fm => xs.reduce((acc, x) => acc.concat(fm(x)), []); const xs = [1,2], ys =[3,4]; _do({chain, of}) () (function*() { const x = yield xs, y = yield ys; return [x + y]; });

No tengo ni idea de cómo empezar. La mónada probablemente sea Id , porque no necesitamos un efecto para este cálculo. Tal vez alguien pueda dar un boceto de cómo se vería una codificación de rutina de la función anterior.

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

over 4 years ago · DIANA MARCELA QUIÑONES RAMOS Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda