Haskell: перенесите обычную функцию в объектив

#haskell #haskell-lens

#haskell #haskell-объектив

Вопрос:

У меня есть HashMap, который содержит различные вещи (значение от Aeson):

 cs :: Hashmap Text Value
cs = fromList [("phone", String " 00"), ("count", Number 1)]
  

Я понял, что могу легко извлекать элементы с помощью линз и, в частности, lens-aeson:

 import Data.Aeson.Lens
import Data.Lens

phone :: Maybe Text
phone = preview (at "phone" . _Just . _String) cs
  

Это работает хорошо.
Но как я могу получить свой счет как Int?
Я пытался:

 count :: Maybe Int
count = preview (at "count" . _Just . _Number) cs
  

Но это возвращает a Maybe Scientific .
Я нашел (в Data-Scientific):

 toBoundedInteger :: forall i. (Integral i, Bounded i) => Scientific -> Maybe i 
  

Как поднять toBoundedInteger , чтобы работать как объектив (или призма) в моем «предварительном просмотре» выше?

Ответ №1:

Используйте folding :

 count :: Maybe Int
count = preview (at "count" . _Just . _Number . folding boundedInteger) cs
  

Существует также to , но это дает вам дополнительный слой Maybe , с которым вам нужно свернуться join :

 count :: Maybe Int
count = preview (at "count" . _Just . _Number . to boundedInteger . to join) cs
  

Комментарии:

1. Спасибо, я думаю, что это хороший ответ. Я пробовал ранее: preview (at "count" . _Just . _Number . _Just . to boundedInteger) cs почему это не работает?

2. После _Number того, как цель имеет тип Scientific , нет Maybe a . _Just является оптическим с типом источника Maybe a ( Fold (Maybe a) a ), в то время to boundedInteger как является оптическим с типом источника Scientific ( Fold Scientific Int ).