Estoy tratando de hacer una función relativamente simple que es casi concat pero con un pequeño giro. Se supone que es binario o juntos los últimos y primeros elementos de cada lista y los combina en el proceso. Estoy trabajando para aprender a escribir código que puede aprovechar las capacidades de Stream Fusion en Data.List.StreamEn Haskell, concat construye una lista perezosamente pero mi propia versión con un giro, no lo hace
Comprobé que el concat en base hace lo que se necesita y construye la lista perezosamente, sin embargo, esta versión I creado no. en la base, concat se especifica de la siguiente manera:
concat :: [[a]] -> [a]
concat = foldr (++) []
(++) :: [a] -> [a] -> [a]
(++) [] ys = ys
(++) (x:xs) ys = x : xs ++ ys
Aquí está mi código:
bconcat :: [[Word8]] -> [Word8]
bconcat = foldr1 bappend
bappend :: [Word8] -> [Word8] -> [Word8]
bappend as bs = init as ++ (last as .|. head bs) : tail bs
La pregunta que tengo es, ¿Cómo escribo esto para que la lista se construye con pereza? Incluso traté de escribir al pasar imitando la definición (++) en la base, pero no hizo la diferencia.
Por el momento, uso el siguiente código, funciona de la manera que quiero, pero el rendimiento se queda atrás concat. Además, utiliza la recursión explícita que me gustaría evitar.
bconcat :: [[Word8]] -> [Word8]
bconcat (a:b:xs) = init a ++ bconcat ((bappend (last a) b):xs)
bconcat (a:[]) = a
bconcat [] = []
bappend :: Word8 -> [Word8] -> [Word8]
bappend !a bs = (a .|. head bs) : tail bs
Por lo tanto, la pregunta que tengo es, ¿Cómo se escribe el código por lo que construye la lista con pereza y sin recursión explícita?
Gracias por su tiempo.
Editar:
Mi principal interés, por el momento, está haciendo un código limpio, conciso y understable con los combinadores estándar. Todavía soy un principiante con un pensamiento funcional y me encantaría ver una forma razonablemente eficiente de ponerlos en práctica aquí.
Supongo que el problema es que tiene que evaluar la primera lista completa antes de poder hacerlo. En mi humilde opinión, no hay evaluación perezosa posible. – fuz
Definitivamente hay una manera de hacerlo construir la lista resultante perezosamente. concat lo logra y hace casi lo mismo. Además, el último fragmento que publiqué lo hago de la manera que quiero. Simplemente no puede alcanzar el nivel de rendimiento de concat. – Elriel
Veo la diferencia, la primera versión OR (última como) con el re –