2016-12-01 3 views
6

डिफ़ॉल्ट पाइप द्वारा पुल आधारित हैं। यह ऑपरेटर >-> के कारण है जो +>> के माध्यम से लागू किया गया है जो कि उसकी पुल श्रेणी के लिए bind ऑपरेटर है। मेरी समझ यह है कि इसका मतलब है कि यदि आपके पास producer >-> consumer जैसे कोड हैं, तो उपभोक्ता के शरीर को पहले कॉल किया जाएगा, फिर डेटा की प्रतीक्षा करने के बाद, निर्माता को बुलाया जाएगा।एक पुल आधारित पाइप को पुश आधारित में कैसे चालू करें?

मैं pipes प्रलेखन here है कि आप एक धक्का आधारित पाइप में एक पुल आधारित पाइप चालू करने के लिए Pipes.Core से कोड (reflect .) उपयोग कर सकते हैं में देखा है। इसका मतलब है (अगर मैं गलत हूं तो मुझे सही करें) कि producer >-> consumer से ऊपर के कोड में, निर्माता पहले चलाया जाता है, एक मूल्य उत्पन्न करता है, तो उपभोक्ता उपभोग करने की कोशिश करता है। यह वास्तव में उपयोगी लगता है और मैं जानना चाहता हूं कि यह कैसे करें।

मैं भी विचार विमर्श here में देखा है >-> करने के लिए कोई धक्का आधारित समकक्ष है कि वहाँ है क्योंकि यह (मैं के साथ मान को प्रतिबिंबित?) के आसपास किसी भी पाइप चालू करने के लिए आसान है, लेकिन मैं वास्तव में यह कैसे करना है समझ नहीं सकता या कोई उदाहरण खोजें

stdin :: Producer String IO r 
stdin = forever $ do 
    lift $ putStrLn "stdin" 
    str <- lift getLine 
    yield str 

countLetters :: Consumer String IO r 
countLetters = forever $ do 
    lift $ putStrLn "countLetters" 
    str <- await 
    lift . putStrLn . show . length $ str 

-- this works in pull mode 
runEffect (stdin >-> countLetters) 

-- equivalent to above, works 
runEffect ((\() -> stdin) +>> countLetters) 

-- push based operator, doesn't do what I hoped 
runEffect (stdin >>~ (\_ -> countLetters)) 

-- does not compile 
runEffect (countLetters >>~ (\() -> stdin)) 

उत्तर

2
-- push based operator, doesn't do what I hoped 
runEffect (stdin >>~ (\_ -> countLetters)) 

मैं यहाँ समस्या इकट्ठा होते हैं कि, जबकि निर्माता पहले अपेक्षा के अनुरूप भाग गया है, पहले का उत्पादन मूल्य गिरा दिया जाता है:

यहाँ कुछ कोड मैं का प्रयास किया गया है। की तुलना करें ...

GHCi> runEffect (stdin >-> countLetters) 
countLetters 
stdin 
foo 
3 
countLetters 
stdin 
glub 
4 
countLetters 
stdin 

... के साथ:

GHCi> runEffect (stdin >>~ (\_ -> countLetters)) 
stdin 
foo 
countLetters 
stdin 
glub 
4 
countLetters 
stdin 

यह समस्या this question को गेब्रियल गोंजालेज 'जवाब से विस्तार से चर्चा की है। यह (>>~) पर आपके द्वारा दिए गए फ़ंक्शन के तर्क को पुश-आधारित प्रवाह में "ड्राइविंग" इनपुट है, और इसलिए यदि आप const इसे दूर करते हैं तो आप पहले इनपुट को छोड़ देते हैं। (मैं

countLettersPush :: String -> Consumer String IO r 
countLettersPush str = do 
    lift $ putStrLn "countLetters" 
    lift . putStrLn . show . length $ str 
    str' <- await 
    countLettersPush str' 
GHCi> runEffect (stdin >>~ countLettersPush) 
stdin 
foo 
countLetters 
3 
stdin 
glub 
countLetters 
4 
stdin 

मैं भी विचार विमर्श here में देखा है >-> करने के लिए कोई धक्का आधारित समकक्ष है, क्योंकि यह किसी भी पाइप चालू करने के लिए चारों ओर आसान है: समाधान तदनुसार countLetters नयी आकृति प्रदान करने के लिए है प्रतिबिंबित करने के साथ लगता है?)

मुझे मेरी जमीन के बारे में पूरी तरह से यकीन नहीं है, लेकिन ऐसा लगता है कि उपर्युक्त समाधान पर काफी लागू नहीं होता है।क्या हम कर सकते हैं करते हैं, अब हम धक्का-आधारित प्रवाह सही ढंग से काम, reflect उपयोग कर रहा है यह पुन: चालू करने के लिए एक पुल आधारित प्रवाह करने के लिए चारों ओर है:

-- Preliminary step: switching to '(>~>)'. 
stdin >>~ countLettersPush 
(const stdin >~> countLettersPush)() 

-- Applying 'reflect', as the documentation suggests. 
reflect . (const stdin >~> countLettersPush) 
reflect . const stdin <+< reflect . countLettersPush 
const (reflect stdin) <+< reflect . countLettersPush 

-- Rewriting in terms of '(+>>)'. 
(reflect . countLettersPush >+> const (reflect stdin))() 
reflect . countLettersPush +>> reflect stdin 

यह वास्तव में पुल आधारित है के रूप में, प्रवाह, नीचे की ओर Clientreflect stdin से प्रेरित है:

GHCi> :t reflect stdin 
reflect stdin :: Proxy String()() X IO r 
GHCi> :t reflect stdin :: Client String() IO r 
reflect stdin :: Client String() IO r :: Client String() IO r 

प्रवाह, तथापि, String रों नदी के ऊपर भेजने के शामिल है, और इसलिए यह (>->) है, जो के रूप में व्यक्त नहीं किया जा सकता है, तो कहते हैं, नीचे की ओर केवल-:

GHCi> -- Compare the type of the second argument with that of 'reflect stdin' 
GHCi> :t (>->) 
(>->) 
    :: Monad m => 
    Proxy a' a() b m r -> Proxy() b c' c m r -> Proxy a' a c' c m 
संबंधित मुद्दे