Haskell, Generi c способ создания Html форм - PullRequest
5 голосов
/ 29 мая 2020

Я создаю сайт в Servant, и мне было интересно, нельзя ли создать экземпляр Generi c для генерации полей ввода.

Я хочу иметь

class ToInputField a where
    toInputField :: a -> InputField

Таким образом, пример реализации может быть

instance ToInputField Text where
    toInputField t = InputField { type = InputText, value = t, name = "some name which I would like to be derived" }

Теперь, если каждая функция доступа определенного типа реализует этот класс, я хотел бы сделать что-то вроде To JSON.

instance ToJSON Person

Но вместо этого сделайте

class ToForm a where
    toForm :: a -> [InputField]

instance ToForm Person

Но вместо этого укажите что-то вроде toInputField :: Text -> a -> InputField, где Text - это имя поля доступа. Итак, toInputField может быть реализован следующим образом

instance ToInputField Text where
    toInputField n t = InputField { type = InputText, value = t, name = n }

У меня такое ощущение, что это возможно с Generics, но у меня нет опыта создания реализации Generi c. Кроме того, я думаю, что должна быть возможность создать реализацию Generi c для

class NamedFunctor a where
    nfmap :: (Text -> b -> c) -> [c]

, где Text - это имя поля доступа. Так что я могу создать форму простым

data Person = Person { pname :: Text, pheight :: Int } deriving (Generic, NamedFunctor)    

toForm :: NamedFunctor a => a -> [InputField]
toForm = nfmap toInputField

Так, что я могу вызвать ее с помощью

show . toForm $ User "testName" 172

и получить

"[ InputField { type = InputText, value = "testName", name = "pname" }
 , InputField { type = InputNumber, value = "172", name = "pheight" }]"

Причина, по которой я спрашиваю об этом более общий вопрос заключается в том, что я не знаю, как бы реализовать что-либо из них, ни простое, ни обобщенное, но я надеюсь, что что-то вроде обобщенного уже реализовано, так как это кажется действительно полезным и может быть использовано для реализации всевозможные вещи, в которых имена полей имеют значение, например, любая сериализация.

...