2009-11-10 20 views
6

लिखने के लिए "नक्शा च (मानचित्र जी XS)" एक कॉल मैप करने के लिए के रूप में आपHaskell, चेनिंग फिल्टर

उदाहरण XS लिख सकता है = नक्शा (FG) xs

लेकिन कैसे होगा आप फ़िल्टर करने के लिए एक कॉल के रूप में "फ़िल्टर पी (फ़िल्टर क्यू एक्सएस)" लिखते हैं? डॉट ऑपरेटर फ़िल्टर के लिए काम नहीं करता है क्योंकि यह नक्शे के लिए करता है। अनुमान है कि आप भविष्यवाणी के लिए कुछ और उपयोग करेंगे?

उत्तर

9

आप एक समारोह both है कि इस तरह देखा परिभाषित हैं:

both :: (a -> Bool) -> (a -> Bool) -> a -> Bool 
both f g x = f x && g x 

तो फिर तुम लिख सकते हैं:

example xs = filter (both p q) xs 

मुझे यकीन है कि एक मानक समारोह है कि आप के लिए यह करता है अगर वहाँ नहीं हूँ। ..

+0

धन्यवाद आदमी, यह सुनिश्चित करता है कि eno ओह। अभी भी सोच रहा है कि ऐसा करने का एक और सीधा तरीका हो सकता है (?) – derp

1

मैं एक सहायक समारोह को परिभाषित करता हूं - शायद यह अधिक घोषणात्मक रूप से लिखा जा सकता है, लेकिन मेरे पास परीक्षण के लिए इस प्रणाली पर जीएचसीआई स्थापित नहीं है:

allPredicates :: [a -> Bool] -> a -> Bool 
allPredicates []  _ = True 
allPredicates (p:ps) x = p x && allPredicates ps x 

तो

filter (allPredicates [p, q]) xs 
+0

'allPredicates = (। फ्लिप ($))। सभी ' – ephemient

+1

फ्लिप करें या थोड़ा कम obfuscated 'allPredicates x y = all (flip ($) y) x'। जीएचसी ने 'फ्लिप' के जटिल उपयोगों को कितना कुशलतापूर्वक उपयोग किया है?मुझे पहले प्रदर्शन उद्देश्यों के लिए 'फ्लिप' के उपयोग को हटाने के लिए प्रतीत होता है। ओह, जॉन की 'ऑलपेडिकेट्स' काफी खराब प्रदर्शन कर सकती है क्योंकि पुनरावर्ती कार्यों को रेखांकित नहीं किया जा सकता है। ओह अजीब, 'सभी 'की' डेटा 'सूची' की परिभाषा में 'जहां जाना है' नहीं है, जिसे मैं निश्चित रूप से सुनिश्चित करता हूं कि आपको इनलाइनिंग की आवश्यकता है। –

+0

आह नहीं, "स्थिर तर्क परिवर्तन" इसे गैर-पुनरावर्ती बनाता है: http://stackoverflow.com/a/9660027/667457 –

6

क्यों एक सूची समझ नहीं?

example = [x | x <- xs, p x, q x] 
-- for example 
example = [x | x <- [1..10], (>3) x, x<5 ] -- [4] 
+0

हाँ, सूची समझ अच्छी तरह से यहां काम करती है। सवाल वास्तव में इस सप्ताह के एक ट्यूटोरियल से उत्पन्न होता है, यह करने का प्रभाव यह करने का एक सीधा तरीका था। सूची समझ अब तक की सबसे तेज़ है और मुझे लगता है कि मानचित्र और "फ़ंक्शन कंपोजिशन" के साथ कोई तुलनात्मक तरीका नहीं हो सकता है। सभी को धन्यवाद! – derp

+0

आप हमेशा एक पुनर्लेखन नियम बना सकते हैं। फ़िल्टर एफ कनवर्ट करें। फिल्टर जी को एक -> फ़िल्टर (एफ ए और& g ए)। बेशक यह अधिक सुरुचिपूर्ण सूची समझ के लिए सिर्फ एक विकल्प है, हालांकि यह तेजी से हो सकता है (घुमावदार)। – codebliss

4

कुछ पर कार्यों की एक सूची कॉलिंग अनिवार्य रूप से Control.Monad में ap समारोह क्या करता है। फिर आप परिणाम and परिणाम। केवल मामूली कुरूपता यह है कि ap दोनों के तर्कों को एक ही मोनड (इस मामले में सूची) में होना आवश्यक है, इसलिए हमें यहां काम करने के लिए return के साथ लिखना होगा।

import Control.Monad 
filterByMany funcs = filter (and . ap funcs . return) 
4

मैं लैम्ब्डा अभिव्यक्ति को परिभाषित करता हूं।

module Main where 

overTen :: Int -> Bool 
overTen = (>10) 

main :: IO() 
main = do 
    print $ filter (\x -> overTen x && even x) [1..20] 

उत्पादन:

$ ghci Test.hs 
GHCi, version 6.10.4: http://www.haskell.org/ghc/ :? for help 
Loading package ghc-prim ... linking ... done. 
Loading package integer ... linking ... done. 
Loading package base ... linking ... done. 
[1 of 1] Compiling Main    (Test.hs, interpreted) 
Ok, modules loaded: Main. 
*Main> main 
[12,14,16,18,20] 
*Main> 
+0

यह है कि 'जीएचसी-ओ 2' स्वचालित रूप से होता है (अच्छी तरह से: पुन: लिखने वाले नियमों के कुछ अलग-अलग चरणों में शामिल होते हैं और अक्सर इंटरमीडिएट चरण फ़िल्टर में वापस आने के बजाय/पहले अन्य सामान के साथ मिलते हैं) –

8
 
$ ghci 
Prelude> :m +Control.Arrow 
Prelude Control.Arrow> :t uncurry (&&) . ((0 <) &&& (< 10)) 
uncurry (&&) . ((0 <) &&& (< 10)) :: (Num a, Ord a) => a -> Bool 
Prelude Control.Arrow> filter (uncurry (&&) . ((0 <) &&& (< 10))) [0..15] 
[1,2,3,4,5,6,7,8,9] 

या अपना स्वयं का ऑपरेटरों यह घोषणा करते हैं कि आप इस बार कर रही हो जाएगा।

infixr 3 &&: 
p &&: q = \a -> p a && q a 
infixr 2 ||: 
p ||: q = \a -> p a || q a 
not' = (.) not 
all' = foldr (&&:) $ const True 
any' = foldr (||:) $ const False 

example xs = filter (p &&: q ||: not' r) xs 
3
import Data.Foldable 
import Data.Monoid 

p = (>4) 
g = (<10) 

main = print $ filter (getAll . foldMap (All.) [p,g]) [1..10] 

आउटपुट

[5,6,7,8,9] 

सिर्फ इसलिए कि सूचियों तह हैं, और आप विधेय परिणामों को जोड़ सकते हैं All साथ monoid

2

क्या की तरह कुछ के बारे में:

example xs = filter (forAll [p,q,r,s,t,u,v]) xs 

forAll:: [(a -> Bool)] -> a -> Bool 
forAll funcs x = all (map ($ x) funcs) 
+0

आपका मतलब था, 'के लिए सभी एफएस एक्स = और [एफएक्स | एफ <- एफएस] '। :) 'all'' के साथ यह सभी fs x = all ($ x) fs' ('map' के बिना) है। :) –