Domanda

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)

È stato utile?

Soluzione

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

Altri suggerimenti

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"

.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top