我正在为两周后的Haskell考试做准备。现在我正在做一些练习,但是我卡在了这个问题上。
实现一个函数
choosing
,它接受2个镜头,并应返回一个可用于Either
值的新镜头。
我被给了这个代码:
type Lens s a = forall f . Functor f => (a -> f a) -> s -> f s
--------------------------------------------------------------
-- Lens s1 a :: Functor f => a -> f a -> s1 -> f s1
-- Lens s2 a :: Functor f => a -> f a -> s2 -> f s2
-- Lens (Either s1 s2) a :: Functor f => a -> f a -> (Either s1 s2) -> f (Either s1 s2)
--------------------------------------------------------------
choosing :: Lens s1 a -> Lens s2 a -> Lens (Either s1 s2) a
choosing lns1 lns2 = undefined
现在,我完全陷入困境。我认为应该使用fmap来解决这个问题,但我不知道如何将这两个镜头组合起来。
所以,在@shang和@klappvisor的帮助下,我找到了这个问题的完整答案:
choosing :: Lens s1 a -> Lens s2 a -> Lens (Either s1 s2) a
choosing lns1 lns2 = (\func x -> case x of
Left value -> (\z -> Left $ set lns1 z value) <$> (func (view lns1 value))
Right value -> (\z -> Right $ set lns2 z value) <$> (func (view lns2 value)))