Pregunta

En Python map () funciona en cualquier dato que siga el protocolo de secuencia. Hace The Right Thing ^ TM ya sea que lo alimente con una cadena o una lista o incluso una tupla.

¿No puedo tener mi pastel en OCaml también? ¿Realmente no tengo otra opción que mirar el tipo de colección que estoy usando y encontrar un List.map o un Array.map o un Buffer.map o un String.map? ¡Algunos de estos ni siquiera existen! ¿Es inusual lo que pido? Debo estar perdiendo algo.

¿Fue útil?

Solución

Lo más cercano a esto es el módulo Enum en Pilas OCaml incluidas (anteriormente de Extlib ). Enum define mapas y se pliega sobre Enum.t ; solo tiene que usar una conversión a / de Enum.t para su tipo de datos. Las conversiones pueden ser bastante ligeras, porque Enum.t es vago.

Lo que realmente quieres es el estilo Haskell clases de tipo , como Plegable y Functor (que generaliza " mapas "). Las bibliotecas de Haskell definen instancias de Plegable y Functor para listas, matrices y árboles. Otra técnica relevante es el " Scrap Your Boilerplate " enfoque a la programación genérica. Dado que OCaml no admite clases de tipo o polimorfismo de tipo superior , no creo podría expresar patrones como estos en su sistema de tipos.

Otros consejos

Hay dos soluciones principales en OCaml:

  1. Jacques Garrigue ya implementó un enfoque sintácticamente ligero pero ineficiente para muchas estructuras de datos hace varios años. Simplemente envuelve las colecciones en objetos que proporcionan un método map . Luego puede hacer collection # map para usar la función de mapa para cualquier tipo de colección. Esto es más general que sus requisitos porque permite que diferentes tipos de estructuras de datos se sustituyan en tiempo de ejecución . Sin embargo, esto no es muy útil en la práctica, por lo que el enfoque nunca se adoptó ampliamente.

  2. Una solución sintácticamente más pesada pero eficiente, robusta y estática es utilizar functores para parametrizar su código sobre la estructura de datos que está utilizando. Esto hace que sea trivial reutilizar su código con diferentes estructuras de datos. Ver las traducciones de Markus Mottl OCaml del libro de Okasaki "Estructuras de datos puramente funcionales" para algunos buenos ejemplos.

Si no está buscando ese tipo de poder y solo quiere ser breve, entonces, por supuesto, puede crear un alias de módulo con un nombre más corto (por ejemplo, módulo S = Cadena).

El problema es que cada contenedor tiene una representación diferente y requiere un código diferente para mapear / reducir para iterar sobre él. Es por eso que hay funciones separadas. La mayoría de los idiomas proporcionan algún tipo de interfaz general para los contenedores (como el protocolo de secuencia que mencionó) para que funciones como map / reduce puedan implementarse de manera abstracta, pero esto no se hace para los tipos que mencionó.

Siempre que defina un tipo t y val compare (: t- > t- > int) en su módulo, Map.Make le dará el mapa que desea.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top