2016-06-23 3 views
4

Während ich veränderbare Vektoren zum ersten Mal benutze, habe ich entdeckt, dass Data.Vector.Unboxed alle Funktionen auf höherer Ebene hat, die man erwartet hätte, wie map, fold, etc., die veränderbare Version Data.Vector.Unboxed.Mutable hat keine davon. Der Versuch, die Funktionen aus dem unveränderlichen Paket auf veränderbaren Vektoren zu verwenden, funktionierte nicht.Haskell veränderbare Vektoren haben keine Karte, Falte, etc ... höhere Funktionen?

Aus welchem ​​Grund fehlen dem veränderbaren Vektorpaket viele dieser Funktionen auf höherer Ebene?

+1

Wird es nicht richtig fusioniert, wenn Sie es als eine Zusammensetzung von 'falten' und' freeze' schreiben? – Cactus

+0

@Cactus Ich habe keine Ahnung. Es gibt keine Dokumentation dazu. – rityzmon

Antwort

3

Ich weiß nicht, was die Designer dieser Typen bei der Implementierung der veränderbaren Versionen im Sinn hatten, aber das Problem, das ich sehe, ist mit Faulheit und der Erwartung von Konsistenz zu tun.

Angenommen, ich erstelle einen veränderbaren Vektor von drei Ints, map (* 2) über sie, und ändern Sie dann den ursprünglichen Vektor. Wenn ich mir die Ausgabe der Karte anschaue, sehe ich doppelte alte Werte oder neue Werte? Die Antwort ist, es hängt davon ab, welche Elemente ich vor dem Modifizieren betrachtet habe und welche danach. Bedenken Sie:

main = do 
    v <- V.replicate 3 1 
    let doubled = map (* 2) v 
    putStrLn "First doubled number is: " ++ show (head doubled) 
    set v 10 
    putStrLn "Sum of doubled numbers is: " ++ show (sum doubled) 

Obwohl wir unsere Operationen durchgeführt in gut definierten Blöcken, bedeutet das Caching von Thunks, dass das erste Element des doubled 2 sein wird, denn wir hatten es zu zwingen, um es zu drucken vor wir setze den ganzen Vektor auf 10, aber die letzten beiden Elemente von doubled werden 20 sein, also ist unsere Summe 42: weder die Summe des Doppelten des ursprünglichen Vektors, noch die Summe des Doppelten des letzten Vektors. Es ist uns gelungen, einen inkonsistenten Zustand zu beobachten, in dem unser System als Ganzes nie sein sollte, weil wir einen veränderlichen Vektor so behandelt haben, als wäre es eine unveränderliche Liste, indem wir versuchen, ihn träge darüber hinweg zu bewegen.

+0

Wie viel würde das für eine _strict_ map gelten? – leftaroundabout

+0

@leftaroundabout Ich bin nicht sicher, weil die Werte selbst immer noch faul sein können. Angenommen, die Funktion, die ich zugeordnet habe, wäre stattdessen '\ x ->" Doppelte Zahl: "++ (x * 2)'. Hätte dies auch in einer strikten Karte das gleiche Problem? Ich bin nicht vertraut genug, wie Haskells Thunking funktioniert. – amalloy

+0

Vielleicht würde es funktionieren, wenn es sowohl streckengerecht als auch wertstreng wäre und jeden Wert zu WHNF zwang. – amalloy