Liste der Showables: OOP schlägt Haskell?

Ich möchte eine Liste verschiedener Dinge erstellen, die eine Eigenschaft gemeinsam haben, nämlich, dass sie in einen String umgewandelt werden könnten. Der objektorientierte Ansatz ist unkompliziert: definieren Sie interfaceShowable und lassen Klassen von Interesse es implementieren. Der zweite Punkt kann im Prinzip ein Problem sein, wenn Sie die Klassen nicht ändern können, aber tun wir so, als wäre dies nicht der Fall. Dann erstellen Sie eine Liste vonShowables und füllen Sie es mit Objekten dieser Klassen ohne zusätzliches Rauschen (z. B. erfolgt das Upcasting normalerweise implizit). Proof of Concept in Javawird hier angegeben.

Meine Frage ist, welche Optionen habe ich in Haskell dafür? Nachfolgend diskutiere ich Ansätze, die ich ausprobiert habe und die mich nicht wirklich befriedigen.

Ansatz 1: existensials. Funktioniert aber hässlich.

{-# LANGUAGE ExistentialQuantification #-}
data Showable = forall a. Show a => Sh a

aList :: [Showable]
aList = [Sh (1 :: Int), Sh "abc"]

Der Hauptnachteil für mich hier ist die Notwendigkeit fürSh beim Ausfüllen der Liste. Dies ähnelt stark Upcast-Operationen, die implizit in OO-Sprachen ausgeführt werden.

Mehr allgemein, der Dummy-WrapperShowable für die Sache, die bereits in der Sprache ist -Show type class - fügt meinem Code zusätzliches Rauschen hinzu. Nicht gut

Ansatz 2: Verbesserungsvorschläge. Gewünscht aber geht nicht.

Der einfachste Typ für eine solche Liste für mich und was ich mir wirklich wünsche wäre:

{-# LANGUAGE ImpredicativeTypes #-}
aList :: [forall a. Show a => a]
aList = [(1 :: Int), "abc"]

Außerdem ie ich gehört ha)ImpredicativeTypes ist "bestenfalls zerbrechlich und schlimmstenfalls kaputt" und wird nicht kompiliert:

Couldn't match expected type ‘a’ with actual type ‘Int’
  ‘a’ is a rigid type variable bound by
      a type expected by the context: Show a => a

und der gleiche Fehler für"abc". (Typ Signatur für 1 beachten: ohne sie bekomme ich noch komischere Meldung:Could not deduce (Num a) arising from the literal ‘1’).

Ansatz 3: Rang-N-Typen zusammen mit einer Art funktionaler Listen (Differenzlisten?).

Anstelle von problematischenImpredicativeTypes man würde wahrscheinlich lieber stabiler und weithin akzeptierterRankNTypes. Das heißt im Grunde: bewegen Sie das gewünschteforall a. Show a => a out of type constructor (d. h.[]) auf einfache Funktionstypen. Folglich brauchen wir eine Darstellung von Listen als einfache Funktionen. Wie ich kaum gehört habe, gibt es solche Darstellungen. Die, von der ich gehört habe, sind Differenzlisten. Aber inDlist package der Haupttyp ist gut altdata Also kehren wir zu den Verbesserungsvorschlägen zurück. Ich habe diese Zeile nicht weiter untersucht, da ich vermute, dass sie ausführlicher als in Ansatz 1 sein könnte. Wenn Sie dies jedoch nicht glauben, geben Sie mir bitte ein Beispiel.

Endeffek: Wie würden Sie eine solche Aufgabe in Haskell angreifen? Könnten Sie eine prägnantere Lösung geben als in der OO-Sprache (insbesondere anstatt eine Liste zu füllen - siehe Kommentar für Code in Ansatz 1)? Können Sie kommentieren, wie relevant die oben aufgeführten Ansätze sind?

UPD (basierend auf ersten Kommentaren): Die Frage wird zum Zwecke der Lesbarkeit natürlich vereinfacht. Das eigentliche Problem besteht eher darin, wie Dinge gespeichert werden, die dieselbe Typklasse haben, d. H. Später auf verschiedene Arten verarbeitet werden können Show hat nur eine Methode, aber andere Klassen können mehr als eine haben. Dadurch werden Lösungen herausgerechnet, die vorschlagen, dass Sie @ anwendeshow Methode direkt beim Ausfüllen einer Liste.

Antworten auf die Frage(16)

Ihre Antwort auf die Frage