2016-10-14 86 views
1

提取JSON字段時,組合棱鏡我有類似下面這樣的JSON斑點:用鏡頭埃宋

[ 
    { 
    "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 

但是,我怎麼能由單次完勝版本的列表列表? 是否有任何鏡頭combinator,其鏡頭AL._Number . to showAL._String . to T.unpack並返回一個聯合吸氣劑,如果第一個失敗,嘗試第二個?像msum鏡片?

回答

2

實際上有一個組合器,它會嘗試光學元件,並在第一個元件失敗時進行備份。它被稱爲failing

請注意,您所描述的情況應滿足條件。即使不是,組合器仍然可以運行,重構時它會表現不規則。 (這與使用filteredTraversal的主要問題。)

+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 

需要注意的是,除非有一些其他的把戲我缺少的,這不僅比卡爾建議也不太靈活更復雜 - 我只能從簡單的功能得到了FoldtryNumberThenString,而failing將棱鏡組合成Traversal