2014-05-07 3 views
6

क्या नीचे मामले में ईटा कमी लागू करना संभव है?ईटा कमी संभव है?

let normalise = filter (\x -> Data.Char.isLetter x || Data.Char.isSpace x) 

मैं कुछ इस तरह संभव हो सकता है उम्मीद कर रहा था:

let normalise = filter (Data.Char.isLetter || Data.Char.isSpace) 

... लेकिन यह नहीं है

उत्तर

10

आपका समाधान काम नहीं करता है, क्योंकि (||)Bool मानों पर काम करता है, और Data.Char.isLetter और Data.Char.isSpaceChar -> Bool प्रकार के हैं।

pl आप देता है:

$ pl "f x = a x || b x" 
f = liftM2 (||) a b 

स्पष्टीकरण: liftM2 लिफ्टों (->) r इकाई को (||), तो यह नया प्रकार है (r -> Bool) -> (r -> Bool) -> (r -> Bool) है।

तो अपने मामले में हम मिल जाएगा:

import Control.Monad 
let normalise = filter (liftM2 (||) Data.Char.isLetter Data.Char.isSpace) 
+10

इस के लिए एक अच्छा जोड़ा ([जे जेब्रमसन से चोरी] [http://stackoverflow.com/questions/21026021/intrigued-by-as-instances-of-monad-and-functor/21026411#comment31608950_21026411) है '(<||>) = liftM2 (||) 'को परिभाषित करने के लिए, फिर आप इसे' फ़िल्टर (isLetter <||> isSpace) 'के रूप में उपयोग कर सकते हैं, और यहां तक ​​कि इन्हें' फिल्टर (isLetter <||> isSpace <||> (== '1')) '। मुझे यह शैली विशेष रूप से उपयोग करने और आकर्षक होने के लिए आसान लगता है। – bheklilr

2

आप Any monoid और वापस लौटने वाले कार्यों के लिए monoid उदाहरण का लाभ ले सकता है मोनोइड मान:

import Data.Monoid 
import Data.Char 

let normalise = filter (getAny . ((Any . isLetter) `mappend` (Any . isSpace))) 
7
import Control.Applicative 
let normalise = filter ((||) <$> Data.Char.isLetter <*> Data.Char.isSpace) 
5

एक अन्य समाधान पर देख लायक तीर शामिल है!

import Control.Arrow 

normalize = filter $ uncurry (||) . (isLetter &&& isSpace) 

&&& दो कार्य (वास्तव में तीर) लेता है और एक साथ एक टपल में उनके परिणाम ज़िप। हम तब || बस अनिश्चित हैं, इसलिए यह समय (Bool, Bool) -> Bool बन गया है और हम सब कुछ कर चुके हैं!

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