I am building a site in Servant, and was wondering if it wouldn't be possible to create a Generic instance for generating input fields.
What I want, is to have a
class ToInputField a where
toInputField :: a -> InputField
Such that, an example implementation could be
instance ToInputField Text where
toInputField t = InputField { type = InputText, value = t, name = "some name which I would like to be derived" }
Now, if every accessor function of a type, implemented this class, I would like to do something like ToJSON.
instance ToJSON Person
But instead do
class ToForm a where
toForm :: a -> [InputField]
instance ToForm Person
But instead have something like toInputField :: Text -> a -> InputField
, where Text is the name of the accessor field. So toInputField
can be implemented like this
instance ToInputField Text where
toInputField n t = InputField { type = InputText, value = t, name = n }
I have a feeling that this is possible with Generics, but I have zero experience creating a Generic implementation. Furthermore, I think it should be possible to create a Generic implementation for
class NamedFunctor a where
nfmap :: (Text -> b -> c) -> [c]
Where Text is the name of the accessor field. Such that I can create a form by simple
data Person = Person { pname :: Text, pheight :: Int } deriving (Generic, NamedFunctor)
toForm :: NamedFunctor a => a -> [InputField]
toForm = nfmap toInputField
Such that I can call it with
show . toForm $ User "testName" 172
And get
"[ InputField { type = InputText, value = "testName", name = "pname" }
, InputField { type = InputNumber, value = "172", name = "pheight" }]"
The reason I ask this more generalized question, is that I don't know how I would implement any of these, neither the simple or generalized one, but I hope something like the generalized has already been implemented, since this seems really useful, and could be used to implement all kinds of things, where the names of fields are relevant, like any serialization.