Estoy tratando de cambiar una lista en haskell para incluir 0 entre cada elemento. Si tenemos una lista inicial [1..20]
, me gustaría cambiarla a[1,0,2,0,3..20]
Lo que pensé en hacer es usar el mapa en cada función, extraer el elemento y luego agregarlo a la lista y usarlo ++[0]
, pero no estoy seguro de si este es el enfoque correcto o no. Todavía estoy aprendiendo Haskell, por lo que podría haber errores
Mi código:
x = map classify[1..20]
classify :: Int -> Int
addingFunction 0 [Int]
addingFunction :: Int -> [a] -> [a]
addingFunction x xs = [a] ++ x ++ xs
No puedes hacer esto con
map
. Una de las propiedades fundamentales demap
es que su salida siempre tendrá exactamente tantos elementos como su entrada, porque cada elemento de salida corresponde a una entrada, y viceversa.Sin embargo, hay una herramienta relacionada con la potencia necesaria:
De esta manera, cada elemento de entrada puede producir cero o más elementos de salida. Puede usar esto para construir la función que desea:
O una definición más concisa de
between
:fuente
Con una coincidencia de patrones simple, debería ser:
fuente
Si desea utilizar
map
para resolver esto, puede hacer algo como esto:Tenga una función que obtenga un int y devuelva una lista de 2 elementos con int y cero:
Entonces puede llamar al mapa con esta función:
Notarás que es una lista anidada. Así es como
map
funciona. Necesitamos una forma de combinar la lista interna en una sola lista. Este caso usamosfoldl
Entonces, la forma en que foldl funciona en este caso es que acepta una función de combinación, un valor inicial y la lista para combinar.
Como no necesitamos el primer 0, podemos soltarlo:
Código final:
fuente
foldl (++) []
es un poco raro ¿Por qué no solo señalarconcat
?concat
implementación en sí misma también usa algún tipo defold
. Así que supongo que usarfoldl
ayudaría a otros a entenderlo un poco más profundo.concat
se implementa utilizando enfoldr
lugar defoldl
. ¿Entiendes por qué esto es realmente importante?fold
mí mismo. Hay toda una wiki relacionada con este tema. Mi simple comprensión es quefoldr
es mucho mejor para la lista infinita perezosa, yfoldl
orfoldl'
(versión estricta) es mejor para el caso de uso general.Aquí podemos hacer uso de un
foldr
patrón donde para cada elemento en la lista original, lo anteponemos con un0
:fuente
Si no desea usar
intersperse
, puede escribir el suyo.Si lo desea, puede usar
Applicative
operaciones:Esta es básicamente la definición utilizada en
Data.Sequence
.fuente