2013-02-04 4 views
5

Ich habe versucht,Haskell: Zeigen Sie alle Elemente, die "sendefähiges" auf einem hList sind

map show . mapMaybe fromDynamic $ [toDyn "one", toDyn (\x -> x::Integer), toDyn 3, toDyn()] 

aber es kehrte

["()"] 
+1

Müssen Sie die Daten in einer solchen Liste wirklich speichern? – AndrewC

+0

Sie könnten beispielsweise einen Datensatz verwenden, um diese Daten viel einfacher zu speichern, und Sie könnten leicht Funktionen wie show für die Elemente verwenden, da die Typen zur Laufzeit verfügbar sind. Die Festlegung von Typen zur Laufzeit ist ein Vorteil, kein Nachteil, also sollten Sie es nach Möglichkeit tun. – AndrewC

+0

Dieses Problem wurde gemacht, um mein Problem zu veranschaulichen. Das Projekt, an dem ich arbeite, ist hier. Github.com/rbarreiro/farofias Der nächste Schritt im Projekt besteht darin, Funktionen hinzuzufügen, die keine Instanz von Data.Data sind. – rbarreiro

Antwort

5

Ihr Code funktioniert nicht so, wie Sie es erwarten. Lange bevor das dynamische Verhalten von Data.Dynamic beginnt, löst der Haskell-Typ-Checker die Typen auf. Die Art des rechten Teils des Ausdrucks ist

mapMaybe fromDynamic $ [toDyn "one", toDyn (\x -> x::Integer), toDyn 3, toDyn()] :: Typeable b => [b] 

und die Art des linken Teils ist

map show :: Show a => [a] -> [String] 

, so dass diese zu kombinieren, die Variable vom Typ b resp. a wird vereinheitlicht. Wenn Sie dies aus einer regulären Haskell-Datei kompilieren würden, würde der Compiler eine Warnung ausgeben (The type variable `a' is ambigous). In GHCi ist der Interpreter jedoch standardmäßig ().

Aber das behebt den Typ fromDynamic im Ausdruck zu Dynamic -> Maybe(), effektiv alle Elemente des Typs () auswählen.

Wenn Sie den Compiler zwingen, dort einen anderen Typ zu verwenden, z. durch eine Art Unterschrift angeben, finden Sie, dass fromDynamic eine andere Art wählen:

Prelude Data.Dynamic Data.Maybe> map (show :: Integer -> String) . mapMaybe fromDynamic $ [toDyn "one", toDyn (\x -> x::Integer), toDyn 3, toDyn()] 
["3"] 

Leider gibt es keine Möglichkeit, zu erreichen, was Sie wollen: alle Elemente eine Show Instanztyp Träger, den wählen, wie die Informationen nicht verfügbar sind zu fromDynamic.

7

Das Problem ist, dass fromDynamic zu einem monomorphic Typ gehen müssen. Es wird () ausgewählt, aber mit einer Typ-Signatur können Sie einen anderen Typ auswählen.

Um es zu zeigen, würden Sie eine Funktion benötigen, die alle möglichen Typen der Reihe nach versucht. Wahrscheinlich möchten Sie die Daten nicht so speichern, sondern mit einigen Operationen (z. B. show) gebündelt speichern.

Es gibt zwei Möglichkeiten, die Sie bündeln könnten. Mein Favorit ist es, alle Funktionen auf den Wert angewendet zu haben (also erhalten Sie für die Show nur eine Liste von Thunks vom Typ String).

Die andere Möglichkeit besteht darin, die Funktionen auch in eine (stellen Sie sicher, dass sie die richtige monomorphe Art sind!) Und dann dynApply verwenden.

+1

nette Idee: "Speichern Sie es mit einigen Operationen gebündelt" – rbarreiro

Verwandte Themen