Подтвердить что ты не робот

Объектив/Призма с обработкой ошибок

Скажем, у меня есть пара функций преобразования

string2int :: String -> Maybe Int
int2string :: Int -> String

Я мог бы довольно легко представить их с помощью оптики.

stringIntPrism :: Prism String Int

Однако, если я хочу представить причину сбоя, мне нужно сохранить их как две отдельные функции.

string2int :: String -> Validation [ParseError] Int
int2string :: Int -> String`

Для этого простого примера Maybe отлично, поскольку мы всегда можем предположить, что сбой - это сбой синтаксического анализа, поэтому нам не нужно его кодировать с использованием типа "Либо" или "Проверка".

Однако представьте, в дополнение к моей разборке Prism, я хочу выполнить некоторую проверку

isOver18 :: Int -> Validation [AgeError] Int
isUnder55 :: Int -> Validation [AgeError] Int

Было бы идеально, чтобы иметь возможность составлять эти вещи вместе, чтобы я мог

ageField = isUnder55 . isOver18 . string2Int :: ValidationPrism [e] String Int

Это довольно тривиально для создания вручную, однако, похоже, достаточно распространенная концепция, что в области линз/оптики может быть что-то скрытое. Есть ли существующая абстракция, которая обрабатывает это?

ТЛ; дг

Существует ли стандартный способ реализации частичного объектива/призмы/изо, который может быть параметризован по произвольному функтору, а не привязан непосредственно к Maybe?.

Я использовал обозначение Haskell выше, так как это более прямолинейно, однако я использую Monocle в Scala для реализации этого. Тем не менее, я был бы доволен ответом, специфичным для библиотеки ekmett Lens.

4b9b3361

Ответ 1

Недавно я написал сообщение в блоге об индексированной оптике; который немного разбирается в том, как мы можем делать также коиндексированную оптику.

Короче: Coindexed-optics возможны, но нам еще предстоит провести там дополнительные исследования. Особенно, потому что, если мы попытаемся перевести этот подход на lens кодирование линз (от Profunctor до VL), он становится еще более волосатым (но я думаю, что мы сможем уйти только с 7 переменными типа).

И мы не можем делать это без изменения того, как индексированная оптика в настоящее время кодируется в lens. Итак, теперь вам лучше использовать определенные для проверки библиотеки.

Чтобы дать подсказку о трудностях: когда мы пытаемся составить с Traversal s, если мы имеем

-- like `over` but also return an errors for elements not matched
validatedOver :: CoindexedOptic' s a -> (a -> a) -> s -> (ValidationErrors, s)

или что-то еще? Если бы мы могли составлять Coindexed Prisms, их значение не будет оправдывать их сложность; они не будут "вписываться" в рамки оптики.