Променете всички четни стойности с леща

Да предположим, че имам масив като този: [1, 2, 3, 4]

Как бих променил само четните стойности с помощта на пакета с обективи? Търся нещо като:

filterLens even (+10) $ [1, 2, 3, 4]
=> [1, 12, 3, 14]

person Vlad the Impala    schedule 06.06.2014    source източник


Отговори (2)


Prelude Control.Lens> [1, 2, 3, 4] & each . filtered even %~ (+ 10)
[1, 12, 3, 14]

За да намерите функции като тази, можете да инструктирате hoogle да търси в пакета с обективи, като поставите "+lens" в полето за търсене. В този случай: http://www.haskell.org/hoogle/?hoogle=%2Blens+filter

person Toxaris    schedule 07.06.2014

Е, ако погледнем вида, който искаме

evens :: Lens' [a] [a]

Изглежда, че трябва да е валиден обектив, стига да не се клатим с дължината на фокусирания списък. Следователно е сравнително лесно да се изгради с помощта на двойки getter и сетълд.

evens = lens get set where
  get (a:b:xs) = b : get xs
  get _ = []

  set [] xs = xs
  set xs [] = xs
  set (x:xs) (y:ys) = x:y:set xs ys

Но ако обърнем голямо внимание на зададената функция, ще видим затруднение при внедряването на пълния filterLens: злоупотребяваме с факта, че знаем точната структура на целта на лещата. Общ filterLens ще трябва да може да реконструира реда, за да изгради отново общия тип, като използва само своята част. За общи типове и предикати това е невъзможно или поне трудно за автоматизиране.

person J. Abrahamson    schedule 06.06.2014