
Leonid
07.12.2017
14:20:38
это понятно, но как пользоваться то?

Egoarka
07.12.2017
14:20:50
@etehtsea https://wiki.haskell.org/Humor

Denis
07.12.2017
14:20:53
@lonokhov агрегирует ворнинги или завершает валидацию на error, сейчас пример покажу

Leonid
07.12.2017
14:21:11
Типов достаточно для документации?

Google

Aleksey
07.12.2017
14:21:26

Leonid
07.12.2017
14:22:20
это же как https://hackage.haskell.org/package/these, только со стейтом?
/me вообще у себя на AccValidation / EitherT наговнякал всякое

Aleksey
07.12.2017
14:23:22
У нас ещё ворнинги есть, т.е. можно получить результат валидации вместе со списком предупреждений

Leonid
07.12.2017
14:23:22
@astynax а что за MonoidMap?
ну так и ChronicleT может

Aleksey
07.12.2017
14:24:05
> Map with Monoid instance which mappend its values
же :)

Leonid
07.12.2017
14:24:12
но зачем?

Denis
07.12.2017
14:24:15
MonoidMap это мап, который клеит ошибки для одного поля
представь что валидируешь веб-форму
для одного поля, может быть несколько проверок, которые на фронт надо отдать
когда агрегируешь в MonoidMap, то они маппендятся

Google

Leonid
07.12.2017
14:25:09
вот я в итоге отказался от такого, ибо тогда имена в формочке просачиваются в бэкенд

Denis
07.12.2017
14:25:25
т.е. один экшен проверяет поле foo одним валидатором, другой - поле foo другие валидатором, а потом они мерджатся в ValidationT монаде

Leonid
07.12.2017
14:25:34
ну это понятно

Denis
07.12.2017
14:25:50
а т.к. ValidationT это трансформер, то можно со своими любыми монадами запускать, в базу там ходить, это всё

Leonid
07.12.2017
14:26:30
а у вас (<*>) == ap?

Aleksey
07.12.2017
14:26:38
Можно по идее параметризовать сам рекорд так, что сами поля будут содержать мету с результатами валидации. Но тут усложняется тип-результат

Denis
07.12.2017
14:26:47
у нас спецрекорды были много где, но потихоньку выпиливаются

Leonid
07.12.2017
14:27:25
ну так у тебя приходит уже рекорд попарсенный, а из него опять именя жсоновые выдавать (ну или формочные)

Denis
07.12.2017
14:27:47
https://github.com/typeable/schematic/blob/master/src/Data/Schematic/Validation.hs#L56
https://github.com/typeable/schematic/blob/master/src/Data/Schematic.hs#L78
у меня не приходит рекорд пропарсенный как раз!
я в хаскелле пишу схему и в хаскелле автоматом валидирую на соответствие её, а если все ок, то конвертирую в что-то более доменно-хаскельное

Leonid
07.12.2017
14:29:25
Я в итогде сделал рекорд попарсенный, ибо валидация таких вещей как "а вот айдишник то есть?" удобнее делать отдельно от парсинга.
ну т.е. ходить в бд
ибо транзакции

Denis
07.12.2017
14:29:45
я отдельно и делаю, там несколько каскадов валидации
самый первый - схема, далее айдишники и все такое прочее

Aleksey
07.12.2017
14:30:30
@catamorphism надо ваять экзампл, походу :)
И вИдение там отразить

Denis
07.12.2017
14:30:34
оба можно делать в ValidationT ErrorType m a, где ErrorType это что-то предсказуемо сериализуемое в ошибку
@astynax ну я так то в курсе что документации нифига нет, руки так и не дошли

Google

Denis
07.12.2017
14:31:00
надо конечно

Aleksey
07.12.2017
14:31:20
Может я экзампл накатаю - на скучных докладах в Минске себя займу :)

Leonid
07.12.2017
14:31:27
ну а что у тебя приходит в функцию которая таки "делает" что-то? рекорд или жсон с шематиками вашими?

Aleksey
07.12.2017
14:31:58
Рекорд

Denis
07.12.2017
14:32:24
смотри, в сервантохендлер приходит изоморфное json значение со схемой типе
JsonRepr MySchema

Leonid
07.12.2017
14:32:46
ну вот, она лезет в базу и узнает что айдишника такого и нет. и как она рапортует? Ей значит нужно знать как поля именуются

Denis
07.12.2017
14:33:07
на нем прогоняется валидация для схемы, далее кастомная валидация, далее конвертится во все что угодно(последние два пункта можно в любом порядке и там it depends)

Leonid
07.12.2017
14:33:19
у вас логика же не в хендлерах

Denis
07.12.2017
14:33:38
у меня требование такое: я хочу чтобы ошибки в ответе json-овом соответствовали тоже определенной схеме
поэтому мне важно получить по результату валидации что-то 1) предсказуемо сериализируемое 2) соответствующее схеме 3) по возможности красивое(это сложнее, где-нибудь какой-нибудь show в поле да проскакивает)

Leonid
07.12.2017
14:35:59
я в итоге сделал кучу ADT с конструкторами в стиле HuitaUserIdDoesNotExit | HuitaTargetSomethingInBadState. фронтендер один чёрт это игнорирует и сам валидирует :(

Denis
07.12.2017
14:41:41
в общем два мотивирующих юзкейса для validationt это 1) валидация крупных форм и запросов, где хочется агрегировать весь список проблем по ключам/jsonpath/xpath 2) валидация непосредственно схем, которая по сути как п.1, но без доменно-специфичных проверок

melancholiac
07.12.2017
14:41:46
полиморфизм можно как то описать в математической нотации?

Denis
07.12.2017
14:42:10
кванторами всеобщности

Leonid
07.12.2017
14:43:28
@catamorphism ну, по моему мнению, валидашка форм и запросов будет без IO. А потом проверки в проблемной области уже будут стучать в бд.
ну и валидашка форм суть парсинг

melancholiac
07.12.2017
14:43:42
по сути полиморфизм это множество отображений из полиморфных типов в некоторый тип?

Denis
07.12.2017
14:43:46
я так и делаю в принципе

Leonid
07.12.2017
14:43:58
иначе не отделить механизм RPC от логики

Google

Denis
07.12.2017
14:44:03
ValidationT ErrorMapWhatever Identity a
а следующий либо в m каком-то, либо в ValidationT ErrorMapWhatever m a

Leonid
07.12.2017
14:44:49
единственный бонус тут в том что ошибки покрасивее, не то что Aeson выдаст

Denis
07.12.2017
14:45:26
я считаю что формат ошибок должен быть максимально предсказуемым, а не как получится

Leonid
07.12.2017
14:45:30
Ну так во вторую ступень уже придет "бизнесс" объект, не?

Denis
07.12.2017
14:45:34
т.к. клиенты вешают всякие обработчики на это

Leonid
07.12.2017
14:45:42
это да

Denis
07.12.2017
14:46:14
в разных случаях, наверное, по разному удобнее
мне нравится что получается четкий decoupling представления API от внутреннего

Admin
ERROR: S client not available

Leonid
07.12.2017
14:46:57
у меня в общем то считай коды для ошибок, только они текстовые и имеют вид errors = [{ code = "HuitaIsBad", title="Bad huita", detail="Huita should not be bad"}, ....]

Denis
07.12.2017
14:47:10
риск сломать API специально каким-то дурацким инстансом падает многократно
мы ошибки структурой отдаем json-овой
там поля отдельные с ошибкой/детализацией

Alister
07.12.2017
14:48:07
фак

Leonid
07.12.2017
14:48:13
Я к тому, что не увидили мы особого смысла в помечании в каком там поле косячное значение. Ну разве что если парсится плохо.

Denis
07.12.2017
14:48:19
ну и плюс эксепшены отрабатываются так, что можно HTTP-код определенный вернуть для определенных ошибок
типа not found
или ошибки валидации

Google

Alister
07.12.2017
14:48:28
я тут себе на голову вызвался писать реализацию перцептрона Розенблата на Prolog

Denis
07.12.2017
14:49:08
@lonokhov ну вот допустим ты хочешь юзера заставить создавать секьюрный пароль

Leonid
07.12.2017
14:49:18
@catamorphism вот да, тоже паттерн матчу ошибки бэкэнда что-бы 404 выдать :)

Denis
07.12.2017
14:49:35
ты хочешь чтобы выполнялось 1) есть цифры 2) есть буквы 3) есть спецсимволы 4) длина достаточная
мне очень не нравится поведение когда ты сабмитишь форму и тебе приезжает ошибка 1

Leonid
07.12.2017
14:50:01
(за первые 3 требования нынче бьют по рукам)

Denis
07.12.2017
14:50:18
ты как юзер правишь пароль, далее приезжает со следующего запроса ошибка 2 и.т.д.

Leonid
07.12.2017
14:50:28
И?

Denis
07.12.2017
14:50:33
я хочу все их агрегировать и отдавать разом

Leonid
07.12.2017
14:50:56
Валидировать аппликативно можно и бизнесс объект
у меня проблема с jsonpath/xpath и прочим
оно не нужно, кмк

Denis
07.12.2017
14:51:13
можно, но тогда ты теряешь путь к полю, которое валидируешь
и его нужно всякими разными способами восстанавливать и протаскивать в обе стороны

Leonid
07.12.2017
14:51:38
ну и чёрт с ним, на фронте путь можно восстановить из ошибки
/me восстаёт против принятых норм HTTP-RPC (aka RESTful)

Denis
07.12.2017
14:52:26
самый главный поинт не в валидации все-таки, основной в том, чтобы представление транспортное(API или как угодно), было отвязано от внутреннего и сериализация/десериализация не зависела от всяких To/From инстансов для конкретных типов

Leonid
07.12.2017
14:53:11
ну так у тебя будут рекорды для месседжей, и рекорды которые там в базе и прочая бизнесс логика. это полюбэ
и маппинг одного в другое будет в хэндлере. а там уже бизнесс пошел
т.е. например часть ты берешь из путей, или хэдеров хттп в одном месте, а в другом где у тебя по вебсокетам часть апи дублируется (ну или еще как) будут из другого места брать. а бэкенд и там и там один и тот же, валидирует свои вещи типа "юзер должен быть" и "батенька, а прав то у вас нет"
но то что parseJSON выдаёт не очень полезную ошибку я согласен. String явно не достаточно.
пусть даже они теперь там путь пишут