Found the solution myself, but leaving this question to help others:
import Data.Data
data D = X Int | Y Int Int deriving (Data,Typeable)
let result = show $ toConstr (X 3) -- result contains what we wanted
Frage
Let us say we have
data D = X Int | Y Int Int | Z String
I wish to have a function getDConst
getDConst :: D -> String
that returns either "X", "Y", or "Z", according to the data constructor used for its input. Is there a generic way to write this without having to do case
on every data constructor? (I am ok with solutions relying on Data.Typeable
or something similar)
Lösung
Found the solution myself, but leaving this question to help others:
import Data.Data
data D = X Int | Y Int Int deriving (Data,Typeable)
let result = show $ toConstr (X 3) -- result contains what we wanted
Andere Tipps
If you don't want to use Typeable
, you can also do this with Show
.
getDConst :: D -> String
getDConst = head . words . show
Show
will not output all the fields, because it is lazy. You can test it runing this code in ghci
:
Prelude> data D = D [Int] deriving (Show)
Prelude> getDConst $ D [1..]
"D"
I have a much basic answer to the question without going through imports or whatever. It's Just a simple mere function.
let's say I have the following data. The repetitive Int in the data definition is intentional because I will use the don't care symbol afterwards:
data YES_NO_CANCEL = YES Int | NO Int Int | CANCEL Int Int Int
then you can make a function as :
extractDataType :: YES_NO_CANCEL -> String
extractDataType YES _ = "YES"
extractDataType NO _ _ = "NO".
extractDataType CANCEL _ _ _ = "CANCEL"
.