Domanda

In Python map () funziona su tutti i dati che seguono il protocollo di sequenza. Fa la cosa giusta ^ TM sia che io gli dia una stringa o un elenco o anche una tupla.

Non posso avere la mia torta anche in OCaml? Non ho davvero altra scelta che guardare il tipo di raccolta che sto usando e trovare un List.map corrispondente o un Array.map o un Buffer.map o un String.map? Alcuni di questi non esistono nemmeno! Ciò che sto chiedendo è insolito? Mi manca qualcosa.

È stato utile?

Soluzione

Il più vicino a questo è il modulo Enum in Batterie OCaml incluse (precedentemente Extlib ). Enum definisce le mappe e le pieghe su Enum.t ; devi solo usare una conversione da / a Enum.t per il tuo tipo di dati. Le conversioni possono essere abbastanza leggere, perché Enum.t è pigro.

Quello che vuoi davvero è in stile Haskell classi di tipi , come Foldable e Functor (che generalizza " mappe "). Le librerie Haskell definiscono le istanze di Foldable e Functor per elenchi, array e alberi. Un'altra tecnica pertinente è la " Scrap Your Boilerplate " approccio alla programmazione generica. Poiché OCaml non supporta classi di tipi o polimorfismo di tipo superiore , non credo saresti in grado di esprimere schemi come questi nel suo sistema di tipi.

Altri suggerimenti

Esistono due soluzioni principali in OCaml:

  1. Jacques Garrigue ha già implementato un approccio sintatticamente leggero ma inefficiente per molte strutture di dati diversi anni fa. Devi semplicemente avvolgere le raccolte in oggetti che forniscono un metodo map . Quindi puoi fare collection # map per usare la funzione map per qualsiasi tipo di raccolta. Questo è più generale dei tuoi requisiti perché consente di sostituire diversi tipi di strutture dati in fase di esecuzione . Tuttavia, ciò non è molto utile nella pratica, quindi l'approccio non è mai stato ampiamente adottato.

  2. Una soluzione sintatticamente più pesante ma efficiente, solida e statica consiste nell'utilizzare i funzioni per parametrizzare il codice sulla struttura dei dati che si sta utilizzando. Ciò rende banale riutilizzare il codice con diverse strutture di dati. Vedi le traduzioni OCaml di Markus Mottl del libro di Okasaki "Strutture di dati puramente funzionali" per alcuni grandi esempi.

Se non stai cercando quel tipo di potere e vuoi solo la brevità, ovviamente, puoi semplicemente creare un alias del modulo con un nome più breve (ad esempio modulo S = String).

Il problema è che ogni contenitore ha una rappresentazione diversa e richiede un codice diverso per mappare / ridurre per iterare su di esso. Questo è il motivo per cui ci sono funzioni separate. La maggior parte delle lingue fornisce una sorta di interfaccia generale per i contenitori (come il protocollo di sequenza che hai citato), quindi funzioni come map / ridurre possono essere implementate in modo astratto, ma ciò non viene fatto per i tipi che hai citato.

Finché definisci un tipo t e val compare (: t- > t- > int) nel tuo modulo, Map.Make ti darà la mappa che desideri.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top