I'm creating an application that allows an admin to build a form, which a user can fill out. Questions can be of different types. Each kind of question corresponds to a type of response data.
Is it possible to encode this at the type level? How would you organize this?
data QuestionType = EmailText | PlainText | Numeric
-- this doesn't have any response information, it's the metadata
-- about the question itself.
data Question = { id :: ID, label :: Text, questionType :: QuestionType }
data Answer = { questionID :: ID, response :: Response }
-- I would like to map those question types to different response types
data Response = ???
-- EmailText => Text
-- PlainText => Text
-- Numeric => Int
I've thought about Type Families, which would work perfectly except that I want to map from different data constructors to different types, and type families would require separate types for each one.
This would be a good fit for a single ADT, with the response information included in each constructor, but I need to be able to deal with question types independently from responses.
How should I approach this?
I've not completely understood what you exactly want, but maybe this can be a starting point:
{-# LANGUAGE DataKinds, GADTs #-}
data Response (qt :: QuestionType) where
RPlainText :: Text -> Response PlainText
REmailText :: Text -> Response EmailText
RNumeric :: Int -> Response Numeric
data Answer qt = Answer {questionID :: ID, response :: Response qt}
If you do not want the qt
argument in Answer qt
, you probably need existential types to hide that, but at that point you'll probably want to link it with the questions somehow.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With