2016-04-14 15 views
5

dire che voglio implementare la funzione di lunghezza per le liste usando il pattern matching, allora avrei potuto fare qualcosa di simile:Come abbinare un vettore vuoto in Haskell?

length' :: (Num b) => [a] -> b 
length' [] = 0 
length' (_:xs) = 1 + length' xs 

Posso fare qualcosa di simile con Vector s?

+3

Puoi usare cose come 'ViewPatterns' e' PatternSynonyms' per associare pattern a cose che sono tipi astratti, ma se vuoi scrivere una funzione induttiva come 'length' su un' Vector', perché non usare solo 'foldl 'o' foldr', o una qualsiasi delle altre dozzine di varianti di "piega" che fornisce 'vector'? Questo ha il vantaggio di generalizzare ogni 'Pieghevole' se si usa per es. 'Data.Foldable.foldr' invece delle versioni specifiche in' vector'. – user2407038

+0

Forse 'case splitAt 1 v of ...'? Forse fatto in un 'ViewPattern', come suggerito sopra. – chi

+3

Fai attenzione ai sinonimi di pattern; possono rompere l'intuizione delle prestazioni se non sono progettate bene. – dfeuer

risposta

3

I vari tipi di libreria vector della libreria Vector sono tipi opachi, che non espongono i loro costruttori di dati e pertanto non è possibile eseguire il modello su di essi.

ci sono modi per aggirare questo, come ViewPatterns (come il commento di user2407038 parla), ma certamente non lo fanno desidera utilizzare questi con vettori, perché si sarebbe probabilmente buttare via il vantaggio di utilizzare vettori .

Il culmine della biblioteca vector è che è attuato sulla base di due concetti:

  1. vettori si materializzano come dimensione fissa, matrici di memoria contigui, che forniscono molto meglio frazione memoria rispetto singolo liste o alberi collegati;
  2. Un numero elevato di operazioni vettoriali viene implementato in termini di flussi fusibili le cui operazioni vengono compilate in loop che non allocano memoria per i vettori intermedi.

(1) significa che un vettore non ha una "testa" naturale "coda" come elenchi do-liste sono letteralmente una coppia di una testa e una coda. Se dovessi utilizzare una sorta di schema di visualizzazione per imporre una struttura di testa + coda sopra un vettore, dovresti creare in modo efficace un elenco a collegamento singolo degli elementi del vettore, che probabilmente attiverebbe l'allocazione della memoria per ciascun nodo del vettore. visualizza il tipo

E se si stesse utilizzando ViewPatterns per visualizzare un vettore come ciò che è effettivamente un singolo elenco collegato, perché non convertire semplicemente il vettore in un elenco?

In ogni caso, a causa dei punti di progetto di cui sopra, con vector si vuole veramente aderire il più possibile al the operations provided by the library itself, perché essi sfrutteranno le caratteristiche prestazionali della biblioteca.

Sospetto che ci siano buone probabilità che testare la dimensione di un vettore possa essere un'idea non ottimale in molti contesti. Ad esempio, nel codice come questo:

example :: Vector something -> Vector somethingElse 
example as 
    | Vector.null as = ... 
    | otherwise  = ... 

... mi aspetterei (ma non l'ho verificato!) Che questo avrebbe costretto il vettore as da materializzato in modo da poter verificare se è vuota o no, dove se il test può essere eliminato o spostato da qualche altra parte è possibile che le operazioni nel bit "..." possano essere fuse con il contesto in cui viene utilizzato example.

+1

'Vector.empty :: Vector a' restituisce effettivamente un vettore vuoto. Dovresti invece usare 'Vector.null :: Vector a -> Bool'. –

+1

@JanGerlinger: Ooops! Buona cattura, è stato corretto ... –

Problemi correlati