Я хотел бы сделать что-то вроде foo ^. x . bar
, где x
будет представлять различные имена, и каждое имя может иметь различный тип: x = {x1 :: X1, x2 :: X2, ..., xn :: Xn}
(псевдокод).
В настоящее время я понимаю, что для каждого x
мне понадобится отдельная линза, но есть ли способ абстрагироваться по промежуточным путям, используя некоторую форму подстановочного знака? Похоже, проблема в настоящее время состоит в том, что не все пути, которые могут быть сгенерированы путем замены в реальных типах (например, из Prism) подстановочного знака x
, будут генерировать допустимые типы, поскольку некоторые типы могут не иметь дочерних узлов соответствующего типа (bar
в примере выше).
В качестве более конкретного примера моя актуальная проблема связана с кодом, сгенерированным из прото-линзы. Имена, соответствующие набору x
, например, prediction
и freshFeatures
в сгенерированном коде ниже:
historical ::
forall f s a.
(Prelude.Functor f,
Data.ProtoLens.Field.HasField s "historical" a) =>
Lens.Family2.LensLike' f s a
historical = Data.ProtoLens.Field.field @"historical"
maybe'dairycompTypes ::
forall f s a.
(Prelude.Functor f,
Data.ProtoLens.Field.HasField s "maybe'dairycompTypes" a) =>
Lens.Family2.LensLike' f s a
maybe'dairycompTypes
= Data.ProtoLens.Field.field @"maybe'dairycompTypes"
maybe'freshFeatures ::
forall f s a.
(Prelude.Functor f,
Data.ProtoLens.Field.HasField s "maybe'freshFeatures" a) =>
Lens.Family2.LensLike' f s a
maybe'freshFeatures
= Data.ProtoLens.Field.field @"maybe'freshFeatures"
maybe'historical ::
forall f s a.
(Prelude.Functor f,
Data.ProtoLens.Field.HasField s "maybe'historical" a) =>
Lens.Family2.LensLike' f s a
maybe'historical = Data.ProtoLens.Field.field @"maybe'historical"
maybe'penCap ::
forall f s a.
(Prelude.Functor f,
Data.ProtoLens.Field.HasField s "maybe'penCap" a) =>
Lens.Family2.LensLike' f s a
maybe'penCap = Data.ProtoLens.Field.field @"maybe'penCap"
maybe'prediction ::
forall f s a.
(Prelude.Functor f,
Data.ProtoLens.Field.HasField s "maybe'prediction" a) =>
Lens.Family2.LensLike' f s a
maybe'prediction = Data.ProtoLens.Field.field @"maybe'prediction"
penCap ::
forall f s a.
(Prelude.Functor f, Data.ProtoLens.Field.HasField s "penCap" a) =>
Lens.Family2.LensLike' f s a
penCap = Data.ProtoLens.Field.field @"penCap"
prediction ::
forall f s a.
(Prelude.Functor f,
Data.ProtoLens.Field.HasField s "prediction" a) =>
Lens.Family2.LensLike' f s a
prediction = Data.ProtoLens.Field.field @"prediction"
prediction
и freshFeatures
, тогда имеют поля key
, которые соответствуют bar
в исходном примере. Поэтому я хотел бы получить доступ к key
без указания родительского типа данных, prediction
, freshFeatures
, et c. Опять же, предостережение в том, что некоторые конструкторы-братья и сестры на одном уровне prediction
и freshFeatures
могут не иметь key
. Я ожидаю, что opti c вернет Nothing
в этом случае и Just key
, если найден key
.
Кроме того, в случае, если это полезно, вот авто сгенерированный код Prism для рассматриваемого конструктора данных:
_DairyCompEntry'PenCap ::
Data.ProtoLens.Prism.Prism' DairyCompEntry'DairycompTypes Proto.Pencap.PerFilePenCapacityData
_DairyCompEntry'PenCap
= Data.ProtoLens.Prism.prism'
DairyCompEntry'PenCap
(\ p__
-> case p__ of
(DairyCompEntry'PenCap p__val) -> Prelude.Just p__val
_otherwise -> Prelude.Nothing)
_DairyCompEntry'Historical ::
Data.ProtoLens.Prism.Prism' DairyCompEntry'DairycompTypes Proto.Historical.PerFileHistoricalData
_DairyCompEntry'Historical
= Data.ProtoLens.Prism.prism'
DairyCompEntry'Historical
(\ p__
-> case p__ of
(DairyCompEntry'Historical p__val) -> Prelude.Just p__val
_otherwise -> Prelude.Nothing)
_DairyCompEntry'Prediction ::
Data.ProtoLens.Prism.Prism' DairyCompEntry'DairycompTypes Proto.CowPrediction.PerFilePredictionData
_DairyCompEntry'Prediction
= Data.ProtoLens.Prism.prism'
DairyCompEntry'Prediction
(\ p__
-> case p__ of
(DairyCompEntry'Prediction p__val) -> Prelude.Just p__val
_otherwise -> Prelude.Nothing)
_DairyCompEntry'FreshFeatures ::
Data.ProtoLens.Prism.Prism' DairyCompEntry'DairycompTypes Proto.FreshFeatures.PerFileFreshFeatureData
_DairyCompEntry'FreshFeatures
= Data.ProtoLens.Prism.prism'
DairyCompEntry'FreshFeatures
(\ p__
-> case p__ of
(DairyCompEntry'FreshFeatures p__val) -> Prelude.Just p__val
_otherwise -> Prelude.Nothing)