2013-05-13 6 views
6

मैं उदाहरण के लिए ए के कुछ लेंस का उपयोग एक समारोह A -> Bool बनाना चाहते हैं predicates। ((>100).(^.foo)) बहुत बेहतर नहीं है। लेंस के बिना, मैं ((>100) . foo) का उपयोग करूंगा।निर्माण लेंस

lens के साथ ऐसी भविष्यवाणियां बनाने का कोई अच्छा तरीका है? आदर्श रूप से यह (\a -> a^.foo > 100 && a^.bar < 50) जैसे भविष्यवाणियों की अनुमति भी देगा।

उत्तर

4

मुझे लगता है कि ((>100).(^.foo)) शायद मानक ऑपरेटर का उपयोग करके आप सबसे अच्छा कर सकते हैं। आप लेंस के लिए नए तुलना ऑपरेटरों को परिभाषित करने को तैयार हैं, तो आप की तरह कुछ कर सकता है:

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 a -> a -> m Bool 
(.==) l = views l . (==) 
infix 4 .== 

(.==.) :: (MonadReader s m, Eq a) => Getting a s a -> Getting a s a -> m Bool 
(.==.) = liftM2 (==) `on` view 
infix 4 .==. 

(.<) :: (MonadReader s m, Ord a) => Getting Bool s a -> a -> m Bool 
(.<) l = views l . flip (<) 
infix 4 .< 

(.<.) :: (MonadReader s m, Ord a) => Getting a s a -> Getting a s a -> m Bool 
(.<.) = liftM2 (<) `on` view 
infix 4 .<. 

(.<=) :: (MonadReader s m, Ord a) => Getting Bool s a -> a -> m Bool 
(.<=) l = views l . flip (<=) 
infix 4 .<= 

(.<=.) :: (MonadReader s m, Ord a) => Getting a s a -> Getting a s a -> m Bool 
(.<=.) = liftM2 (<=) `on` view 
infix 4 .<=. 


(.>) :: (MonadReader s m, Ord a) => Getting Bool s a -> a -> m Bool 
(.>) l = views l . flip (>) 
infix 4 .> 

(.>.) :: (MonadReader s m, Ord a) => Getting a s a -> Getting a s a -> m Bool 
(.>.) = liftM2 (>) `on` view 
infix 4 .>. 

(.>=) :: (MonadReader s m, Ord a) => Getting Bool s a -> a -> m Bool 
(.>=) l = views l . flip (>=) 
infix 4 .>= 

(.>=.) :: (MonadReader s m, Ord a) => Getting a s a -> Getting a s a -> 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 .||. 

ऑपरेटर विकल्पों के पीछे तर्क है कि डॉट ओर एक लेंस है कि प्रतीक है, तो आप लिख सकते हैं या तो foo .== 5 या foo .==. bar (जहां foo और bar लेंस हैं)। दुर्भाग्यवश, lens पैकेज भी अपने (.<) ऑपरेटर को परिभाषित करता है, इसलिए शायद कुछ अन्य नामकरण सम्मेलन बेहतर होगा। यह सिर्फ पहला विचार था जो मेरे दिमाग में आया था।

इन नए ऑपरेटर का उपयोग करना, आप की तरह

l' = filter (foo .> 100 .&&. bar .< 50) l 
+0

यह महान है सामान लिखने में सक्षम हो जाएगा! मुझे आश्चर्य है कि क्या कुछ ऐसा करने के लिए बहु-पैरामीटर प्रकार कक्षाओं का उपयोग करना है><= काम? –

संबंधित मुद्दे