2013-08-18 10 views
11

Lassen Sie uns sagen, wir habenHaskell: Get Daten Konstruktor Namen als String

data D = X Int | Y Int Int | Z String 

ich eine Funktion getDConst

getDConst :: D -> String 

haben wollen, die entweder "X" zurückkehrt, "Y" oder " Z ", entsprechend dem Datenkonstruktor, der für seine Eingabe verwendet wird. Gibt es eine generische Möglichkeit, dies zu schreiben, ohne auf jedem Datenkonstruktor case zu machen? (Ich bin ok mit Berufung Lösungen auf Data.Typeable oder so ähnlich)

Antwort

13

die Lösung selbst gefunden, sondern lassen diese Frage, anderen zu helfen:

import Data.Data 
data D = X Int | Y Int Int deriving (Data,Typeable) 

let result = show $ toConstr (X 3) -- result contains what we wanted 
+1

Wenn jemand anderes auch einen Fehler mit dieser bekommt: Versuchen Sie, '{- # SPRACHE DeriveDataTypeable # -}' auf den Anfang der Datei. Es ist in GHC erforderlich, wenn Sie Data und Typable ableiten. – jPlatte

6

Wenn Sie nicht Typeable verwenden möchten, können Sie auch Tun Sie dies mit Show.

getDConst :: D -> String 
getDConst = head . words . show 

Show nicht ausgegeben werden alle Felder, weil sie faul ist. Sie können es testen diesen Code in ghci runing:

Prelude> data D = D [Int] deriving (Show) 
Prelude> getDConst $ D [1..] 
"D" 
+0

Sie können auch eine benutzerdefinierte Show-Ausgabe implementieren, die nicht den Konstruktor enthält. – kqr

+0

'show' ist faul, also wird das wahrscheinlich nicht sehr langsam sein. Beachten Sie, wie 'take 5 (show (Just undefined))' gut funktioniert. –

+2

Sie meinen 'Wörter', nicht' unwords'. (Eigentlich würde ich so etwas wie 'Takewhile (/ =‘ ‚) schreiben. Show') – Lynn