haskell - Construct predicates with lenses -
i want create function a -> bool
using lenses of a. instance:
data = { _foo :: int, _bar :: int } makelenses ''a l :: [a] l' = filter (\a -> a^.foo > 100) l
the filter predicate looks bit clumpsy. ((>100).(^.foo))
not better. without lenses, use ((>100) . foo)
.
is there nice way create such predicates lens
? ideally allow predicates (\a -> a^.foo > 100 && a^.bar < 50)
.
i think ((>100).(^.foo))
best can using standard operators. if willing define new comparison operators lenses, like:
import control.lens hiding ((.>)) import control.monad (liftm2) import control.monad.reader (monadreader) import data.function (on) (.==) :: (monadreader s m, eq a) => getting bool s -> -> m bool (.==) l = views l . (==) infix 4 .== (.==.) :: (monadreader s m, eq a) => getting s -> getting s -> m bool (.==.) = liftm2 (==) `on` view infix 4 .==. (.<) :: (monadreader s m, ord a) => getting bool s -> -> m bool (.<) l = views l . flip (<) infix 4 .< (.<.) :: (monadreader s m, ord a) => getting s -> getting s -> m bool (.<.) = liftm2 (<) `on` view infix 4 .<. (.<=) :: (monadreader s m, ord a) => getting bool s -> -> m bool (.<=) l = views l . flip (<=) infix 4 .<= (.<=.) :: (monadreader s m, ord a) => getting s -> getting s -> m bool (.<=.) = liftm2 (<=) `on` view infix 4 .<=. (.>) :: (monadreader s m, ord a) => getting bool s -> -> m bool (.>) l = views l . flip (>) infix 4 .> (.>.) :: (monadreader s m, ord a) => getting s -> getting s -> m bool (.>.) = liftm2 (>) `on` view infix 4 .>. (.>=) :: (monadreader s m, ord a) => getting bool s -> -> m bool (.>=) l = views l . flip (>=) infix 4 .>= (.>=.) :: (monadreader s m, ord a) => getting s -> getting s -> m bool (.>=.) = liftm2 (>=) `on` view infix 4 .>=. (.&&.) :: monad m => m bool -> m bool -> m bool (.&&.) = liftm2 (&&) infix 3 .&&. (.||.) :: monad m => m bool -> m bool -> m bool (.||.) = liftm2 (||) infix 3 .||.
the logic behind operator choices dot signifies side has lens, write either foo .== 5
or foo .==. bar
(where foo
, bar
lenses). unfortunately, lens
package defines own (.<)
operator, maybe other naming convention better. first idea came mind.
using these new operators, able write stuff like
l' = filter (foo .> 100 .&&. bar .< 50) l
Comments
Post a Comment