Question

En Python, map () fonctionne sur toutes les données qui suivent le protocole de séquence. C’est bon, que je lui donne une chaîne, une liste ou même un tuple.

Puis-je avoir mon gâteau dans OCaml aussi? Est-ce que je n'ai vraiment pas d'autre choix que de regarder le type de collection que j'utilise et de trouver un List.map, un Array.map, un Buffer.map ou un String.map correspondant? Certaines d'entre elles n'existent même pas! Est-ce que ce que je demande est inhabituel? Je dois manquer quelque chose.

Était-ce utile?

La solution

Le module le plus proche de vous est le module Énumération dans les piles OCaml incluses (anciennement de Extlib ). Enum définit les cartes et se replie sur Enum.t ; vous devez simplement utiliser une conversion vers / depuis Enum.t pour votre type de données. Les conversions peuvent être assez légères, car Enum.t est paresseux.

Ce que vous voulez vraiment, ce sont des classes de type de style Haskell, comme Pliable et Functor (qui généralise les "cartes"). Les bibliothèques Haskell définissent les instances de Foldable et Functor pour les listes, les tableaux et les arborescences. Une autre technique pertinente est la " Scrap Your Boilerplate " approche de la programmation générique. Étant donné qu'OCaml ne prend pas en charge les classes de type ou le polymorphisme de type supérieur , je ne pense pas. vous seriez capable d'exprimer des motifs comme ceux-ci dans son système de type.

Autres conseils

Il existe deux solutions principales dans OCaml:

  1. Jacques Garrigue a déjà mis en œuvre une approche syntaxiquement légère mais inefficace pour de nombreuses structures de données il y a plusieurs années. Vous venez d’envelopper les collections dans des objets fournissant une méthode map . Ensuite, vous pouvez utiliser collection # map pour utiliser la fonction map pour n’importe quel type de collecte. Ceci est plus général que vos exigences car il permet de substituer différents types de structures de données au moment de l'exécution . Toutefois, comme cela n’est pas très utile dans la pratique, cette approche n’a jamais été largement adoptée.

  2. Une solution syntaxiquement plus lourde mais efficace, robuste et statique consiste à utiliser des foncteurs pour paramétrer votre code sur la structure de données que vous utilisez. Cela rend trivial la réutilisation de votre code avec différentes structures de données. Voir les traductions OCaml de Markus Mottl du livre d'Okasaki "Structures de données purement fonctionnelles". pour quelques bons exemples.

Si vous ne recherchez pas ce type de pouvoir et que vous voulez juste être bref, vous pouvez bien sûr créer un alias de module avec un nom plus court (par exemple, module S = Chaîne).

Le problème est que chaque conteneur a une représentation différente et nécessite un code différent pour mapper / réduire et itérer dessus. C'est pourquoi il y a des fonctions séparées. La plupart des langages fournissent une sorte d’interface générale pour les conteneurs (comme le protocole de séquence que vous avez mentionné). Ainsi, des fonctions telles que mapper / réduire peuvent être implémentées de manière abstraite, mais cela n’est pas le cas pour les types que vous avez mentionnés.

Tant que vous définissez un type t et val comparez (: t- > t- & int) dans votre module, Map.Make vous donnera la carte de votre choix.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top