2013-03-12 5 views
10

Ich weiß, es gibt fst und snd, aber warum gibt es keine "allgemeine" Definition für solche Accessor-Funktionen mit Typklassen? Ich würde so etwas wieWarum gibt es keine "allgemeinen" Accessor-Funktionen für Tupel in Haskell?

class Get1 p a | p -> a where 
    get1 :: p -> a 

instance Get1 (a,b) a where 
    get1 (x,_) = x 

instance Get1 (a,b,c) a where 
    get1 (x,_,_) = x 

class Get2 p a | p -> a where 
    get2 :: p -> a 

instance Get2 (a,b) b where 
    get2 (_,x) = x 

instance Get2 (a,b,c) b where 
    get2 (_,x,_) = x 

Sure vorschlagen, müssen Sie einige Spracherweiterungen für diese, aber nicht diese viel bequemer wie das? Insbesondere können Sie Instanzen für Ihre eigenen Typen hinzufügen.

+4

Diese und andere Tupel-Extras sind im Paket [tuple] (http://hackage.haskell.org/package/tuple) verfügbar. – is7s

+0

@is7s Danke, ich wusste nicht – Landei

+9

Die Antwort ist wahrscheinlich "weil niemand Tupel sehr viel verwendet". Sicherlich keine großen. – MathematicalOrchid

Antwort

6

Eine Sache zu beachten ist, dass und snd nur erlauben, in ein 2-Tupel zu sehen. Verallgemeinern sie zu anderen Aritäten und Operationen wird schnell schmerzhaft. Wenn Sie beispielsweise auch das erste Element eines Tupels abbilden wollen, müssen Sie einen anderen Kombinator einführen (der für 2-Tupel als Control.Arrow.first existiert). Dies führt schnell zu einer Explosion der Anzahl von Kombinatoren für hohe Tupel.

Das gesagt, lens bietet einige nette Tools zum Arbeiten mit Tupeln. Control.Lens.Tuple bietet mehrere Index-Linsen _1, _2 usw., die den Zugriff auf die erste erlauben, zweite usw. Elemente von Tupeln bis zu arity 9.

Zum Beispiel

>>> import Control.Lens 
>>> let t = (1,2,3,5,6,7,2) 
>>> t ^._1 
1 
>>> t & _1 .~ 'a' 
('a',2,3,5,6,7,2) 
>>> t & _1 +~ 41 
(42,2,3,5,6,7,2) 
>>> over _1 (+1) t 
(2,2,3,5,6,7,2) 

können Sie auch Interesse an den Tupel Instanzen in Control.Lens.At. Außerdem bietet die tuple-lenses einige allgemeinere Linsen für die gleichzeitige Untersuchung mehrerer Tupeleinträge.

3

Solche Klassen geben nur Codierung (Syntax) Bequemlichkeit, ich sehe nicht, wie generalisiert über Tupel-Tools auf sie zu bauen. Wenn Sie nach Tupel Generalisierung suchen, überprüfen Sie the discussion about heterogeneous vectors auf Reddit.

Beachten Sie auch, dass es für normale Strukturen vorzuziehen ist, eigene ADTs zu definieren und Getter mit sinnvollen Namen zu versehen und dann Tupel mit hoher Priorität zu verwenden.

Edit: jedoch, wie is7s im Kommentar gezeigt, gibt es eine Reihe von Paketen auf Hackage, die Indexierungsfunktionen für Tupel beliebiger Länge bieten.

+1

Nein, das Paket, auf das ich Bezug nehme, wird nicht mit 'TemplateHaskell' implementiert. Das Modul "Data.Tuple.Select" wird ähnlich wie das OP implementiert. – is7s

Verwandte Themen