2016-10-12 39 views
5

muszę funkcji takich jak <<%~ który działałby z Traversal s w podobny sposób do ^? coś takiego:analogowe z `<<% ~` nie wymagając monoid dla Traversal

(<<?%~) :: Traversal s t a b -> (a -> b) -> s -> (Maybe a, t) 

> ix 0 <<?%~ succ $ [1,2] 
(Just 1,[2,2]) 
> ix 1 <<?%~ succ $ [1,2] 
(Just 2,[1,3]) 
> ix 2 <<?%~ succ $ [1,2] 
(Nothing,[1,2]) 

Jak należy zaimplementować? Oczywistym sposobem jest zastosowanie ^? i %~ osobno, ale chciałbym rozwiązać za jednym razem.

Odpowiedz

4

Jeśli nie chcemy wymagać ograniczenia dla celów, musimy określić się jako Monoid, który będzie używany do łączenia starych elementów podczas przemierzania. Ponieważ celem jest coś analogicznego do ^?, odpowiednim monoidem jest First.

(<<?%~) :: LensLike ((,) (First a)) s t a b -> (a -> b) -> s -> (Maybe a, t) 
l <<?%~ f = first getFirst . (l $ \a -> (First (Just a), f a)) 
+3

Zmieniłem ramkę wokół rozwiązania dość drastycznie. Możesz je cofnąć, jeśli ich nie lubisz. – duplode

+0

@duplode dzięki. Smutno, nie mogę odpowiedzieć na to pytanie :) – modular