4

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.

Chris Wohlert
  • 610
  • 3
  • 12

0 Answers0