2017-06-19 12 views
9

Szukam filtru przejścia, a następnie wybierz ostatni element do użycia z over.Przechodzenie przez ostatni element "przefiltrowanego"

np. coś w tym stylu (ale które faktycznie się skompiluje):

[1,2,3,4] & traverse . filtered even . _last +~ 10 
> [1,2,3,14] 

Jakieś pomysły?

P.S. Jestem świadomy, że filtered jest poprawny tylko wtedy, gdy nie wpływa na liczbę elementów w przemianie.

Rzeczywistym przypadkiem użycia, który wykonuję, jest wybranie tylko najniższego poziomu rekursywnego przejścia uniplate pasującego do pewnego predykatu; jeśli masz inne pomysły, jak to zrobić, chciałbym je usłyszeć!

+0

Miałem pęknięcie w tym celu przechodząc w transformatorze stanu odwróconego monady, ale to daje podpis 'MonadFix m => Traversal 'sa -> LensLike' msa', który nie jest zbyt użyteczny - możesz tylko wstawiać do niego wartości, nie wyciągać ich, ponieważ 'Const s' nie jest' Monad'. Alternatywnym podejściem byłoby pobranie długości kolekcji przez złożenie, a następnie zliczenie stanowe aż do ostatniego indeksu - który dałby ograniczenie "Monad" zamiast "MonadFix" kosztem pewnej wydajności. Przechodzenie przez konkretną listę, jak w odpowiedzi @ Gurkenglasa, jest prawdopodobnie najlepszym rozwiązaniem –

Odpowiedz

1

To nie jest odpowiedź, tylko kontynuacja @Gurkenglas, która jest za duża na komentarz. Zauważ, że @ Gurkenglas za odpowiedź:

let t = partsOf (traverse . filtered even) . _last 

może wyglądać jak Traversal, ale tak nie jest, nawet jeśli utrzymują liczbę elementów, ponieważ narusza drugie prawo przemierzanie (z oczywistych powodów):

let f = Identity . succ 
[1,2,3,4] & fmap (t f) . t f -- yields [1,3,3,5] effectively 
[1,2,3,4] & getCompose . t (Compose . fmap f . f) 
           -- yields [1,2,3,6] effectively 

na to, aby być przechodzenie, trzeba utrzymać zarówno liczyć element i własnością filtrowanie jako niezmienników.

czy to będzie miało znaczenia dla aplikacji, nie wiem, ale po prostu mieć świadomość, że partsOf pochodzi z tego rodzaju ostrzeżenia, a dokumentacja mylnie sugeruje, że wynik partsOf będzie obiektywu jeśli utrzymują element liczyć. (To jest prawdziwe dla partsOf each, przykład podany w dokumentacji, ale nie w ogóle.)

2
[1,2,3,4] & partsOf (traverse . filtered even) . _last +~ 10