2015-07-31 21 views
7

In F # abbiamo List.partition e Array.partition che restituiscono rispettivamente una tupla di liste e una tupla di array.Perché non c'è Seq.partition in F #

quindi, perché non c'è Seq.partition restituire una tupla di sequenze?

ecco un molto semplice implementazione: F# Snippets

così ... perché non è questa parte del nucleo?

risposta

15

In F # 4.0 (Visual Studio 2015), le librerie di base sono molto più uniformi rispetto a prima, ma non vengono ancora implementate con Seq.partition. Puoi trovare ulteriori informazioni al riguardo nella discussione sul design in lingua F #: Regular functional operators producing two or more output collections.

Il riepilogo è che la funzione Seq.partition è piuttosto complicata e l'averla potrebbe introdurre potenziali problemi di prestazioni. C'è un paio di modi in cui può lavorare:

  • Può iterare la collezione di ingresso per due volte (come la versione FsSnip), che può causare problemi se si dispone di complessi calcoli in ritardo (si sta facendo tutto due volte)

  • Può scorrere l'input una volta, ma poi dovrebbe fare una condivisione di stato mutabile complessa (che potrebbe allocare segretamente memoria).

Quindi, Seq.partition non può essere attuato ragionevolmente, mantenendo tutte le buone caratteristiche che ci si aspetta sul tipo seq<'T>.

+0

Ma 'Seq.partition' è fondamentalmente solo una versione specializzata di' Seq.groupBy', che già risolve i problemi sollevati. Quindi, dal momento che abbiamo quest'ultimo, potremmo semplicemente implementare il primo come involucro attorno ad esso senza creare ulteriori preoccupazioni. Vedi la mia proposta di implementazione qui sotto. – brianberns

1

Seq.partition è solo una versione specializzata di Seq.groupBy, quindi la libreria standard potrebbe implementare il precedente come un wrapper attorno a quest'ultimo senza introdurre nuovi problemi.

let partition predicate source = 
    let map = 
     source 
      |> Seq.groupBy predicate 
      |> Map.ofSeq 
    let get flag = 
     map 
      |> Map.tryFind flag 
      |> Option.defaultValue Seq.empty 
    get true, get false 
+0

Aggiungi un po 'di contesto al tuo codice per spiegare la tua risposta in modo più completo. Ciò aggiungerà valore per i futuri visitatori. – miken32

+0

@ miken32: Fatto. – brianberns

Problemi correlati