En todos los lugares que he intentado usar map
, también fmap
ha funcionado. ¿Por qué los creadores de Haskell sintieron la necesidad de una map
función? ¿No podría ser simplemente lo que se conoce actualmente fmap
y fmap
podría eliminarse del idioma?
97
fmap
. Es mapear una función sobre una instancia de Functor. Me pregunto cuál es el propósito de la especializaciónmap
.Respuestas:
Me gustaría dar una respuesta para llamar la atención sobre el comentario de augustss :
Haskell 98 es visto como un paso atrás por algunos Haskellers (incluyéndome a mí), ya que las versiones anteriores han definido una biblioteca más abstracta y consistente. Oh bien.
fuente
map and fmap
ha existido durante mucho tiempo - fue recalentado en la lista de correo de Haskell-prime en agosto de 2006 - haskell.org/pipermail/haskell-prime/2006-August/thread.html . Como contrapunto, prefiero el statu quo. Para mí, parece valioso que haya un subconjunto de Haskell que se corresponda aproximadamente con Miranda. En el Reino Unido, Miranda se utilizó como lenguaje de enseñanza para estudiantes de matemáticas, no solo para estudiantes de ciencias de la computación. Si ese nicho aún no se ha perdido en un lenguaje no funcional (por ejemplo, Mathematica), no veo a Haskell con unmap
relleno unificado .Citando de la
Functor
documentación en https://wiki.haskell.org/Typeclassopedia#Functorfuente
Se ven iguales en el sitio de la aplicación, pero son diferentes, por supuesto. Cuando aplica cualquiera de esas dos funciones,
map
ofmap
, a una lista de valores, producirán el mismo resultado, pero eso no significa que estén destinadas al mismo propósito.Ejecute una sesión de GHCI (el Glasgow Haskell Compiler Interactive) para consultar información sobre esas dos funciones, luego eche un vistazo a sus implementaciones y descubrirá muchas diferencias.
mapa
Consulte GHCI para obtener información sobre
map
y verá que se define como una función de orden superior aplicable a una lista de valores de cualquier tipo que
a
produce una lista de valores de cualquier tipob
. Aunque polimórfica (a
yb
en la definición anterior representan cualquier tipo), lamap
función está destinada a aplicarse a una lista de valores que es solo un tipo de datos posible entre muchos otros en Haskell. Lamap
función no se pudo aplicar a algo que no sea una lista de valores.Como puede leer en el código fuente de GHC.Base , la
map
función se implementa de la siguiente maneraque hace uso de la coincidencia de patrones para sacar la cabeza (the
x
) de la cola (thexs
) de la lista, luego construye una nueva lista usando el:
constructor de valores (contras) para anteponerf x
( léalo como "f aplicado ax" ) a la recursividad demap
over the tail hasta que la lista esté vacía. Vale la pena notar que la implementación de lamap
función no depende de ninguna otra función, sino de sí misma.fmap
Ahora intente consultar información sobre
fmap
y verá algo bastante diferente.Este tiempo
fmap
se define como una de las funciones cuyas implementaciones deben proporcionar aquellos tipos de datos que deseen pertenecer a laFunctor
clase de tipos. Eso significa que puede haber más de un tipo de datos, no solo el tipo de datos "lista de valores" , capaz de proporcionar una implementación para lafmap
función. Eso lo hacefmap
aplicable a un conjunto mucho mayor de tipos de datos: ¡los functores de hecho!Como puede leer en el código fuente de GHC.Base , una posible implementación de la
fmap
función es la proporcionada por elMaybe
tipo de datos:y otra posible implementación es la proporcionada por el tipo de datos de 2 tuplas
y otra posible implementación es la proporcionada por el tipo de datos de la lista (¡por supuesto!):
que se basa en la
map
función.Conclusión
La
map
función se puede aplicar nada más que a una lista de valores (donde los valores son de cualquier tipo) mientras que lafmap
función se puede aplicar a muchos más tipos de datos: todos aquellos que pertenecen a la clase functor (por ejemplo, maybes, tuplas, listas, etc. ). Dado que el tipo de datos "lista de valores" también es un funtor (porque proporciona una implementación para él), entoncesfmap
se puede aplicar y producir el mismo resultado quemap
.fuente