Question

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)

Was it helpful?

Solution

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

OTHER TIPS

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"

.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top