У меня есть следующий фрагмент кода, который считывает значение, указанное выражением линзы (lens-aeson
):
import Control.Lens ((^?))
import Data.Aeson (Value)
import Data.Aeson.Key (fromString)
import Data.Aeson.Lens (key)
import Data.Text (pack)
-- >>> readValue
-- Just (String "value")
readValue :: Maybe Value
readValue = json ^? path
where
path = key (fromString "key") . key (fromString "of") . key (fromString "interest")
json = pack "{\"key\": {\"of\": {\"interest\": \"value\"}}}"
Теперь я хочу динамически построить выражение path
из конфигурации, передав список ["key","of","interest"]
в readValue
.
Как я могу динамически создать path
из списка?
Что-то вроде этого, я думаю:
readValue = json ^? _Value.path
where
path = foldr (.) id [key (fromString t) | t <- ["key", "of", "interest"]]
json = pack "{\"key\": {\"of\": {\"interest\": \"value\"}}}"
Вы можете соединить foldr
и понимание списка вручную, если вам это очень важно.
@K.A.Buhr Странно. Это сработало для меня. Интересно, чем отличаются наши установки?
Похоже, что это расширение DeepSubsumption
, представленное в версии 9.2.4, которое Haskell98
включено из соображений совместимости, но отключено для других языков по умолчанию. (А с NoDeepSubsumption
оригинал не компилируется.)
Отлично, это работает для меня. Спасибо Даниэлю Вагнеру и К.А. Бур. Я работаю с GHC 9.6.5 и языковой версией GHC2021. Возможно, эта информация будет полезна для вас, @Daniel Wagner.
Оригинальное решение мне не удалось из-за более высокого ранга
key
. Я отредактировал его с помощью понимания списка, который, кажется, работает правильно.