Estoy usando Conduit para analizar algunos datos en forma de flujo. En algún momento de la secuencia, necesito cada 12º elemento. ¿Existe alguna forma conveniente de hacer esto?

Actualmente estoy esperando explícitamente 12 elementos solo para devolver el primer elemento:

get12th :: Monad m => Conduit Int m Int
get12th = loop
  where
    loop = do
        v1 <- await
        _ <- await
        _ <- await
        _ <- await
        _ <- await
        _ <- await
        _ <- await
        _ <- await
        _ <- await
        _ <- await
        _ <- await
        _ <- await
        case v1 of
            Nothing -> return ()
            Just x -> do
              yield x >> loop

Funciona, pero me pregunto si esta es la mejor manera de hacerlo.

2
Thomas Vanhelden 15 dic. 2016 a las 20:20

2 respuestas

La mejor respuesta

Gracias a Alec, Chad Gilbert y Michael Snoyman, he llegado a la siguiente solución:

get12th :: Monad m => Conduit Int m Int
get12th = loop
  where loop = do
          v <- await
          case v of
            Just x  -> yield x >> CL.drop 11 >> loop
            Nothing -> return ()

Esta solución usa la función drop para deshacerse de las esperas duplicadas. Entrega el primer valor tan pronto como lo recibe, antes de esperar los otros valores.

2
Thomas Vanhelden 17 dic. 2016 a las 16:11

Puede usar replicateM_ para deshacerse de esas await líneas duplicadas.

v1 <- await
replicateM_ 11 await
case v1 of
   ...
7
Chad Gilbert 15 dic. 2016 a las 17:25