2016-10-14 10 views
1

У меня есть JSON блоб, подобные следующие:Объединение призм при извлечении JS полей с объективом-эсоном

[ 
    { 
    "version": 1 
    }, 
    { 
    "version": "3" 
    }, 
    ... 
] 

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

v1 :: [String] 
v1 = obj ^.. AL.values . AL.key fieldName . AL._Number . to show 

И следующее, чтобы извлечь строки

v2 :: [String] 
v2 = obj ^.. AL.values . AL.key fieldName . AL._String . to T.unpack 

Но, как я могу получить список версий на один проход над список? Есть ли комбинатор линз, который снимает линзы AL._Number . to show и AL._String . to T.unpack и возвращает комбинированный геттер, чтобы, если первый из них не удался, он пытается выполнить второй? Что-то вроде msum для линз?

ответ

2

Существует, по сути, комбинатор, который пытается использовать оптику и переходит к резервной копии, если первый из них не работает. Это называется failing.

Обратите внимание, что условие на нем должно удовлетворять случаю, который вы описываете. Даже если это не так, комбинатор все равно будет функционировать, он будет вести себя нерегулярно при рефакторинге. (Что является основной проблемой, с использованием filtered как Traversal.)

+0

Ницца. Я подозревал, что ответ будет в «Control.Lens.Traversal», но мои глаза прошли мимо этого комбинатора среди всех остальных :) – duplode

+0

@duplode Я полностью понимаю. Там есть * много *. – Carl

0

Перед Carl's answer, которая является то, что вы должны использовать, я собирался предложить outside как способ для выполнения анализа ситуации с этими призмами:

tryNumberThenString :: AL.AsPrimitive t => t -> [String] 
tryNumberThenString = 
    outside AL._Number .~ (:[]) . show $ 
    outside AL._String .~ (:[]) . T.unpack $ 
    const [] 
v1 = obj ^.. AL.values . AL.key fieldName . folding tryNumberThenString 

Обратите внимание, что, если не существует какой-либо другой трюк, мне не хватает, это не только более сложным, чем Карл предлагает, но и менее гибким - я могу только получить Fold от обычной функции tryNumberThenString, а failing объединяет призмы в Traversal.