2011-09-06 12 views
6

ho una struttura di dati in Clojure che rappresenta una serie di risultati di un esperimento:Devo implementare l'interfaccia Seq in clojure

(defprotocol ResultSet 
    (columns [rs] "return a collection of the columns in the resultset, represented by keywords") 
    (rows [rs] [rs column-keys] "returns a seq of the rows in the resultset, order and column specified as keywords by column-keys. with a single argument returns rows with all columns present")) 

e ho un deftype che implementa questo protocollo. Sono interessato a scrivere funzioni che fanno cose come mappare una funzione su tutti i risultati nel set di risultati, o che piegano il set di risultati, fondamentalmente facendo le stesse cose delle funzioni seq incorporate.

In Haskell lo farei implementando i tipi di caratteri pertinenti (es. Functor) e quindi utilizzando funzioni come fmap o mfilter. Così ho cercato di farlo in Clojure e ho trovato alcune idee sull'implementazione dell'interfaccia ISeq.

Quindi, questa è una buona idea? Non riesco a trovare molte risorse sull'implementazione di ISeq e mi chiedo quale sia l'approccio idiomatico a questo.

risposta

5

Per quanto posso dire, il modo "migliore" per implementare qualcosa di simile non è implementare ISeq, ma clojure.lang.Seqable; in altre parole, fornire un'implementazione di (.seq) per mappare il ResultSet su una sequenza (eventualmente pigra). Questo è il percorso che il clojure utilizza per la maggior parte (tutti?) Le raccolte tranne la lista (le liste implementano ISeq, perché l'API seq è già un sottoinsieme dell'API elenco).

+0

Questo mi consentirà di fare qualcosa come restituire la sequenza sottostante di righe in un set di risultati, ma non mi permette di mappare una funzione su un 'Risultati' e di ottenere un risultato' lo fa? EDIT: Ho appena realizzato che la mappa integrata non si comporta in questo modo, forse sto cercando di fare la cosa sbagliata. –

+1

Come dici nella tua modifica, le funzioni di sequenza del clojure generalmente chiamano (seq) sulla raccolta fornita e poi lavorano e restituiscono seq, non un tipo specifico di raccolta. All'inizio sembra un po 'poco intuitivo, ma in pratica funziona davvero bene. Tutto ciò di cui hai veramente bisogno è un modo per restituire un seq al tipo di raccolta che ti serve, quando ne hai veramente bisogno (che non è tutto così spesso, una volta che stai lavorando su seqs) potrebbe valere la pena di valutare se hai bisogno un tipo ResultSet a tutti) –

0

Penso di aver frainteso la tua domanda, ma non ti basta usare la mappa per applicare una funzione a ciascun elemento nel risultato.

Problemi correlati