2012-05-31 16 views
9

मेरे पास एक साधारण कार्य है - फाइल से लाइनों का एक समूह पढ़ें और उनमें से प्रत्येक के साथ कुछ करें। पहले को छोड़कर - जो कुछ शीर्षकों को अनदेखा किया जा सकता है।एक पाइपलाइन में कंड्यूट ड्रॉप फ़ंक्शन का उपयोग कैसे करें?

तो मैंने सोचा कि मैं कंडिशन का प्रयास करूंगा।

printFile src = runResourceT $ CB.sourceFile src =$= 
    CT.decode CT.utf8 =$= CT.lines =$= CL.mapM_ putStrLn 

कूल।

तो अब मैं सिर्फ बंद ... पहली पंक्ति ड्रॉप करना चाहते हैं और उसके लिए एक समारोह हो रहा है -

printFile src = runResourceT $ CB.sourceFile src =$= 
    CT.decode CT.utf8 =$= CT.lines =$= drop 1 =$= CL.mapM_ putStrLn 

हम्म - लेकिन अब मैं ड्रॉप हस्ताक्षर Sink a m() टाइप है नोटिस। - किसी ने मुझे सुझाव दिया कि मैं effectfully कुछ तत्वों ड्रॉप करने के पाइप और उपयोग ड्रॉप के लिए इकाई उदाहरण उपयोग कर सकते हैं तो मैं इस कोशिश की:

drop' :: Int -> Pipe a a m() 
drop' n = do 
    CL.drop n 
    x <- await 
    case x of 
    Just v -> yield v 
    Nothing -> return() 

कौन सा जाँच टाइप नहीं है क्योंकि पाइप के लिए इकाई उदाहरण केवल पाइप पर लागू होता है उसी प्रकार के - सिंक के पास उनके आउटपुट के रूप में शून्य है, इसलिए मैं इसका उपयोग इस तरह नहीं कर सकता।

मैंने पाइप और पाइप-कोर पर एक त्वरित नज़र डाली और मैंने देखा कि पाइप-कोर में यह कार्य है जैसा कि मैंने उम्मीद की थी, जहां पाइप एक न्यूनतम लाइब्रेरी है लेकिन दस्तावेज दिखाता है कि इसे कैसे कार्यान्वित किया जाएगा।

तो मैं कर रहा हूँ उलझन में - हो सकता है वहाँ एक महत्वपूर्ण अवधारणा मैं याद कर रहा हूँ है .. मैं समारोह

sequence :: Sink input m output -> Conduit input m output 

लेकिन वह, सही विचार होना करने के लिए के रूप में उत्पादन मूल्य है प्रतीत नहीं होता देखा ()

CL.sequence (CL.drop 1) :: Conduit a m()  

मैं शायद सिर्फ वापस जाएँ और आलसी-कब का उपयोग के रूप में मैं वास्तव में किसी भी स्ट्रीमिंग की जरूरत नहीं है जाएगा - लेकिन मैं यह करने के लिए उचित तरीके से देखने के लिए दिलचस्पी होगी।

उत्तर

6

सबसे पहले, सरल जवाब:

... =$= CT.lines =$= (CL.drop 1 >> CL.mapM_ putStrLn) 

अधिक व्याख्या की: वहाँ वास्तव में दो अलग अलग तरीकों आप drop लागू कर सकते हैं। किसी भी तरह से, यह पहले इनपुट से n तत्वों को छोड़ देगा। इसमें आगे क्या करता है के बारे में दो विकल्प हैं:

  • कहते हैं यह इनपुट धारा से शेष आइटम के सभी outputting
  • प्रारंभ किया है

पूर्व व्यवहार क्या एक Sink प्रदर्शन करेंगे (और हमारे drop वास्तव में क्या करता है) जबकि उत्तरार्द्ध Conduit का व्यवहार है। आप वास्तव में monadic रचना के माध्यम से पूर्व से बाद उत्पन्न कर सकते हैं:

dropConduit n = CL.drop n >> CL.map id 

तो फिर तुम dropConduit उपयोग कर सकते हैं के रूप में आप शुरुआत में वर्णन करते हैं। यह monadic संरचना और फ्यूजिंग के बीच अंतर का प्रदर्शन करने का एक अच्छा तरीका है; पूर्व दो कार्यों को एक ही इनपुट स्ट्रीम पर संचालित करने की अनुमति देता है, जबकि बाद में एक समारोह दूसरे को स्ट्रीम करने की अनुमति देता है।

मैंने बेंचमार्क नहीं किया है, लेकिन मैं काफी हद तक निश्चित हूं कि monadic संरचना थोड़ा और अधिक कुशल होगा।

+0

हम्म - सरल उत्तर अच्छी तरह से काम करता है, धन्यवाद। ड्रॉपकंडिट 'मोनाड एम => इंट -> पाइप शून्य शून्य एम()' जो मुझे लगता है कि मुझे लगता है कि किसी भी चीज़ के लिए उपयोग करना मुश्किल है? – Oliver

+0

क्षमा करें, मैं कोडबेस के एक अलग संस्करण पर काम कर रहा हूं जहां यह लागू नहीं होगा। कंड्यूट 0.4 ​​में, आपको 'सिंकटॉइप (CL.drop n) >> CL.map id' होना चाहिए। मुद्दा यह है कि Data.Conduit.List में प्रकार अत्यधिक प्रतिबंधित हैं। कंड्यूट 0.5 उन्हें आराम देगा। –

+0

अहह - चीयर्स। यह समझ आता है। – Oliver

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