Ответ 1
Нашел решение самостоятельно, но оставив этот вопрос, чтобы помочь другим:
import Data.Data
data D = X Int | Y Int Int deriving (Data,Typeable)
let result = show $ toConstr (X 3) -- result contains what we wanted
Скажем, мы имеем
data D = X Int | Y Int Int | Z String
Я хочу иметь функцию getDConst
getDConst :: D -> String
который возвращает либо "X", "Y", либо "Z", в соответствии с конструктором данных, используемым для его ввода. Есть ли общий способ написать это, не делая case
для каждого конструктора данных? (Я в порядке с решениями, основанными на Data.Typeable
или чем-то подобном)
Нашел решение самостоятельно, но оставив этот вопрос, чтобы помочь другим:
import Data.Data
data D = X Int | Y Int Int deriving (Data,Typeable)
let result = show $ toConstr (X 3) -- result contains what we wanted
Если вы не хотите использовать Typeable
, вы также можете сделать это с помощью Show
.
getDConst :: D -> String
getDConst = head . words . show
Show
не выводит все поля, потому что он ленив. Вы можете проверить его запуск этого кода в ghci
:
Prelude> data D = D [Int] deriving (Show)
Prelude> getDConst $ D [1..]
"D"
Как отметил Николас Хенин в комментарии, другие упомянутые решения опираются на стандартную реализацию Show
. Лучшим подходом является тот, который описан на fooobar.com/info/2448128/....