Как только призма фокусируется, она теряет контекст. Поэтому я не вижу способа определить _result
в терминах _one
и _another
. Но вы, безусловно, можете добиться большего успеха, чем прибегнуть к unsafePartial
:
import Data.Lens.Lens (Lens', lens)
import Data.Profunctor.Choice ((|||), (+++))
type OneAnother = Either Int Int
_result :: Lens' OneAnother Int
_result = lens getter setter
where
getter = identity ||| identity
setter e x = (const x +++ const x) e
Украл это из репозитория profunctor-lens
:
-- | Converts a lens into the form that `lens'` accepts.
lensStore :: forall s t a b . ALens s t a b -> s -> Tuple a (b -> t)
lensStore l = withLens l (lift2 Tuple)
Это не экспортируется как-то. С этой помощью следующее решение должно быть достаточно c:
import Prelude
import Control.Apply (lift2)
import Data.Lens.Common
import Data.Lens.Lens
import Data.Lens.Prism
import Data.Profunctor.Choice ((|||), (+++))
import Data.Tuple
_result :: Lens' OneAnother Int
_result = lens getter setter
where
getter = identity ||| identity
setter e x = (const x +++ const x) e
lensStore :: forall s t a b . ALens s t a b -> s -> Tuple a (b -> t)
lensStore l = withLens l (lift2 Tuple)
data ABC
= A Int
| B (Tuple Boolean Int)
| C OneAnother
lensABCInt :: Lens' ABC Int
lensABCInt = lens' case _ of
A i -> map A <$> lensStore identity i
B i -> map B <$> lensStore _2 i
C i -> map C <$> lensStore _result i
Здесь ABC
- ваш тип целевой суммы. Пока у каждого его варианта есть объектив, у вас есть объектив для него в целом.