हास्केल रचना (?) बनाम एफ # के पाइप फॉरवर्ड ऑपरेटर (!>)


100

F # में, पाइप-फॉरवर्ड ऑपरेटर का उपयोग, |>बहुत सामान्य है। हालाँकि, हास्केल में मैंने केवल फंक्शन कंपोज़िशन देखा है (.), जिसका इस्तेमाल किया जा रहा है। मैं समझता हूं कि वे संबंधित हैं , लेकिन क्या कोई भाषा कारण है कि पाइप-फॉरवर्ड हास्केल में उपयोग नहीं किया गया है या यह कुछ और है?


2
lihanseys का उत्तर है कि &हास्केल है |>। इस धागे में गहराई से दफन हो गया और मुझे कुछ दिनों के लिए खोजा। मैं इसका बहुत उपयोग करता हूं, क्योंकि आप स्वाभाविक रूप से अपने कोड का पालन करने के लिए बाएं से दाएं पढ़ते हैं।
itmuckel

जवाबों:


61

मैं थोड़ा सट्टा लगा रहा हूँ ...

संस्कृति : मुझे लगता |>है कि एफ # "संस्कृति" में एक महत्वपूर्ण ऑपरेटर है, और शायद .हास्केल के लिए भी ऐसा ही है। F # का फंक्शन कंपोजिशन ऑपरेटर है, <<लेकिन मुझे लगता है कि F # कम्युनिटी हास्केल कम्युनिटी की तुलना में पॉइंट-फ्री स्टाइल का इस्तेमाल करती है।

भाषा अंतर : मुझे तुलना करने के लिए दोनों भाषाओं के बारे में पर्याप्त जानकारी नहीं है, लेकिन शायद लेट-बाइंडिंग को सामान्य बनाने के नियम इसको प्रभावित करने के लिए पर्याप्त रूप से भिन्न हैं। उदाहरण के लिए, मैं एफ # में कभी-कभी लिखना जानता हूं

let f = exp

संकलन नहीं करेंगे, और आपको स्पष्ट एटा-रूपांतरण की आवश्यकता होगी:

let f x = (exp) x   // or x |> exp

संकलन करने के लिए। यह लोगों को पॉइंट-फ़्री / कंपोज़िअल स्टाइल से और पाइपलाइनिंग स्टाइल से दूर रखता है। इसके अलावा, एफ # प्रकार का अनुमान कभी-कभी पाइपलाइनिंग की मांग करता है, ताकि बाईं ओर एक ज्ञात प्रकार दिखाई दे ( यहां देखें )।

(व्यक्तिगत रूप से, मुझे अंक-मुक्त शैली अप्राप्य लगती है, लेकिन मुझे लगता है कि जब तक आप इसके आदी नहीं हो जाते, तब तक मैं हर नई / अलग चीज को अपठनीय मानता हूं।)

मुझे लगता है कि दोनों भाषा में संभावित रूप से व्यवहार्य हैं, और इतिहास / संस्कृति / दुर्घटना यह परिभाषित कर सकती है कि प्रत्येक समुदाय एक अलग "आकर्षित करने वाले" पर क्यों बसे।


7
मैं सांस्कृतिक मतभेदों से सहमत हूं। पारंपरिक हास्केल का उपयोग करता है .और $, इसलिए लोग उनका उपयोग करना जारी रखते हैं।
आमोक

9
बिंदु मुक्त कभी-कभी बिंदु से अधिक पठनीय होता है, कभी-कभी कम। मैं आमतौर पर नक्शे और फिल्टर जैसे कार्यों के तर्क में इसका इस्तेमाल करता हूं, ताकि लंबोदर के अव्यवस्थित होने से बचा जा सके। मैं कभी-कभी इसे शीर्ष-स्तरीय कार्यों में भी उपयोग करता हूं, लेकिन कम बार और केवल जब इसका कुछ सीधा होता है।
पॉल जॉनसन

2
मुझे इसमें ज्यादा संस्कृति दिखाई नहीं देती है, इस मायने में कि बस इस मामले में कोई विकल्प नहीं है जहां तक ​​एफ # चिंतित है (कारणों के लिए आप और गणेश का उल्लेख है)। तो मैं कहूंगा कि दोनों हास्केल में व्यवहार्य हैं, लेकिन पाइपलाइन ऑपरेटर का उपयोग करने के लिए एफ # निश्चित रूप से बेहतर है।
कर्ट शेलफथआउट 15

2
हां, बाएं से दाएं पढ़ने की संस्कृति :) यहां तक ​​कि गणित को भी इस तरह से पढ़ाया जाना चाहिए ...
निकोलस

1
@nicolas दाएं से बाएं एक मनमाना विकल्प है। आप बाएं से दाएं की आदत डाल सकते हैं।
मार्टिन कैपोडिसी

86

F # (|>)में बाएं से दाएं टाइपकास्टिंग की वजह से महत्वपूर्ण है। उदाहरण के लिए:

List.map (fun x -> x.Value) xs

आम तौर पर टाइपकास्ट नहीं किया जाएगा, क्योंकि भले ही प्रकार xsज्ञात हो, लंबोदर के तर्क xका प्रकार उस समय नहीं जाना जाता है जब टाइपकर्ता इसे देखता है, इसलिए यह नहीं जानता कि कैसे हल करना हैx.Value

इसके विपरीत

xs |> List.map (fun x -> x.Value)

ठीक काम करेगा, क्योंकि प्रकार के प्रकार के xsलिए नेतृत्व करेंगेx ज्ञात होने ।

जैसे निर्माणों में शामिल नाम रिज़ॉल्यूशन के कारण बाएं से दाएं टाइपकास्टिंग आवश्यक है x.Value। साइमन पेयटन जोन्स ने हास्केल के लिए इसी तरह के नाम के प्रस्ताव को जोड़ने के लिए एक प्रस्ताव लिखा है , लेकिन वह सुझाव देते हैं कि स्थानीय बाधाओं का उपयोग करके यह पता लगाया जाए कि एक प्रकार किसी विशेष ऑपरेशन का समर्थन करता है या नहीं। इसलिए पहले नमूने में जिस संपत्ति की आवश्यकता होती है xउसे Valueतब तक आगे बढ़ाया जाएगा जब तक कि xsउसे देखा न जाए और इस आवश्यकता को हल किया जा सके। हालांकि यह टाइप सिस्टम को जटिल करता है।


1
दिलचस्प यह है कि हास्केल में (<|) ऑपरेटर के समान है (दाएं-बाएं डेटा की समान दिशा)। लेकिन इसके लिए कैसे काम करेगा संकल्प?
the_Ghost

7
(<|) वास्तव में हास्केल ($) के समान है। लेफ्ट-टू-राइट टाइपकास्टिंग केवल आवश्यक चीजों को हल करने के लिए आवश्यक है। वेल, इसलिए (<|) अन्य परिदृश्यों में ठीक काम करता है, या यदि आप स्पष्ट प्रकार एनोटेशन का उपयोग करते हैं।
जीएस -

44

अधिक अटकलें, इस बार मुख्य रूप से हास्केल की ओर से ...

($)(|>)जब आप बिंदु-रहित कोड नहीं लिख सकते हैं, तो इसका फ्लिप ऑफ है , और इसका उपयोग काफी आम है। तो (|>)हास्केल में इस्तेमाल नहीं होने का मुख्य कारण यह है कि इसका स्थान पहले से ही है($)

इसके अलावा, एफ # अनुभव के एक बिट से बोलते हुए, मुझे लगता (|>)है कि एफ # कोड में इतना लोकप्रिय है क्योंकि यह Subject.Verb(Object)ओओ की संरचना जैसा दिखता है । चूंकि F # एक चिकनी कार्यात्मक / OO एकीकरण के लिए लक्ष्य कर रहा है, Subject |> Verb Objectनए कार्यात्मक प्रोग्रामर के लिए एक बहुत ही चिकनी संक्रमण है।

व्यक्तिगत रूप से, मुझे बाएं से दाएं भी सोचना पसंद है, इसलिए मैं (|>)हास्केल में उपयोग करता हूं , लेकिन मुझे नहीं लगता कि कई अन्य लोग करते हैं।


हाय नाथन, "फ्लिप ($)" हैस्केल प्लेटफ़ॉर्म में कहीं भी पूर्वनिर्धारित है? नाम "(|>>)" पहले से ही Data.Sequence में एक और अर्थ के साथ परिभाषित किया गया है। यदि पहले से परिभाषित नहीं है, तो आप इसे क्या कहते हैं? मैं "($>) = फ्लिप ($)" के साथ जाने की सोच रहा हूं
मटभ

2
@ मत्तभ: ऐसा नहीं है कि मैं हुगले से मिल सकता हूं। मैं इसके बारे में नहीं जानता था Data.Sequence.|>, लेकिन $>वहाँ टकराव से बचने के लिए उचित लगता है। ईमानदारी से, केवल बहुत सारे अच्छे दिखने वाले ऑपरेटर हैं, इसलिए मैं बस |>दोनों का उपयोग करूंगा और केस-बाय-केस आधार पर टकराव का प्रबंधन करूंगा । ((मुझे भी सिर्फ उर्फ ​​के Data.Sequence.|>रूप में प्रलोभन दिया जाएगा snoc)
नाथन शाइली-सैंडर्स

2
($)और (|>)आवेदन नहीं रचना कर रहे हैं। दो (प्रश्न नोटों के रूप में) से संबंधित हैं लेकिन वे एक ही नहीं कर रहे हैं (अपने fcहै (Control.Arrow.>>>)कार्यों के लिए)।
नाथन श्लीट-सैंडर्स 16

11
व्यवहार में, F # का |>वास्तव में |कुछ और से अधिक UNIX की याद दिलाता है।
केविन कैन्टू

3
|>F # में एक और लाभ यह है कि इसमें Visual Studio में IntelliSense के अच्छे गुण हैं। टाइप करें |>, और आपको उन कार्यों की एक सूची मिलती है जिन्हें बाईं ओर के मूल्य पर लागू किया जा सकता है, जो .किसी वस्तु के बाद टाइप करने पर होता है ।
क्रिस्टोफर जॉनसन

32

मुझे लगता है कि हम चीजों को भ्रमित कर रहे हैं। हास्केल का ( .) F # 's ( >>) के बराबर है । एफ # के s ( |>) के साथ भ्रमित नहीं होना चाहिए, जो कि केवल फ़ंक्शन अनुप्रयोग उल्टा है और हास्केल की तरह है ( $) - उल्टा:

let (>>) f g x = g (f x)
let (|>) x f = f x

मेरा मानना ​​है कि हास्केल प्रोग्रामर $अक्सर उपयोग करते हैं। शायद जितनी बार F # प्रोग्रामर का इस्तेमाल करते हैं उतनी बार नहीं |>। दूसरी ओर, कुछ F # लोग >>हास्यास्पद डिग्री का उपयोग करते हैं: http://blogs.msdn.com/b/ashleyf/archive/2011/04/04/21/programming-is-pointless.aspx


2
जैसा कि आप कहते हैं कि यह हास्केल के $ऑपरेटर की तरह है - उलट है, तो आप इसे आसानी से परिभाषित भी कर सकते हैं: a |> b = flip ($)जो F # की पाइपलाइन के बराबर हो जाता है जैसे कि आप तब कर सकते हैं[1..10] |> map f
विज़

8
मुझे लगता है ( .) के रूप में ही ( <<), जबकि ( >>) रिवर्स रचना है। वह है ( >> ) : ('T1 -> 'T2) -> ('T2 -> 'T3) -> 'T1 -> 'T3बनाम( << ) : ('T2 -> 'T3) -> ('T1 -> 'T2) -> 'T1 -> 'T3
डोबेस वांडरमेर

-1 के लिए "का प्रयोग करें> एक ​​हास्यास्पद डिग्री के लिए"। (खैर, मैंने ऐसा नहीं किया लेकिन आपको मेरी बात सही लगी)। एफ # में एफ "कार्यात्मक" के लिए है, इसलिए फ़ंक्शन रचना वैध है।
फ्लोरियन एफ

1
निश्चित रूप से मैं मानता हूं कि फ़ंक्शन संरचना वैध है। "कुछ एफ # लोग" द्वारा मैं अपने आप को संदर्भित कर रहा हूं! कि मेरा अपना ब्लॉग। : पी
एशलेफ़

मुझे नहीं लगता कि .इसके बराबर है >>। मुझे नहीं पता कि अगर एफ # है, <<लेकिन यह समकक्ष (एल्म की तरह) होगा।
मैट जॉइनर

28

यदि आप |>Haskell में F # का उपयोग करना चाहते हैं तो Data.Function में &ऑपरेटर (तब से base 4.8.0.0) है।


हास्केल के लिए किसी भी कारण से चयन करने के लिए &खत्म हो गया |>? मुझे लगता है कि |>यह बहुत अधिक सहज है, और यह मुझे यूनिक्स पाइप ऑपरेटर की भी याद दिलाता है।
येशेंगम

16

हास्केल में बाएँ से दाएँ रचना

कुछ लोग हास्केल में भी बाएं से दाएं (संदेश-पास) शैली का उपयोग करते हैं। उदाहरण के लिए, Hackage पर mps लाइब्रेरी देखें। एक उदाहरण:

euler_1 = ( [3,6..999] ++ [5,10..999] ).unique.sum

मुझे लगता है कि यह शैली कुछ स्थितियों में अच्छी लग रही है, लेकिन इसे पढ़ना कठिन है (एक पुस्तकालय और उसके सभी ऑपरेटरों को जानना आवश्यक है, पुनर्परिभाषित (.) भी परेशान है)।

कंट्रोल पैकेज, बेस पैकेज के हिस्से में बाएं से दाएं और बाएं से बाएं कंपोजिशन ऑपरेटर्स भी हैं । तुलना >>>और <<<क्रमशः:

ghci> :m + Control.Category
ghci> let f = (+2) ; g = (*3) in map ($1) [f >>> g, f <<< g]
[9,5]

कभी-कभी बाएं से दाएं रचना को पसंद करने का एक अच्छा कारण है: मूल्यांकन आदेश पढ़ने के आदेश का पालन करता है।


अच्छा है, इसलिए (>>>) काफी हद तक (|>) के बराबर है?
खानजोर

@ खानजोर बिल्कुल नहीं। (> |) एक तर्क लागू करता है, (>>>) ज्यादातर फ़ंक्शन रचना (या इसी तरह की चीजें) है। तब मुझे लगता है कि कुछ निश्चितता अंतर है (इसकी जांच नहीं की)।
सातनिन

15

मैंने देखा >>>है के लिए इस्तेमाल किया जा रहा हैflip (.) , और मैं अक्सर खुद का उपयोग करता हूं, विशेष रूप से लंबी श्रृंखलाओं के लिए जिन्हें बाएं से दाएं सबसे अच्छा समझा जाता है।

>>> वास्तव में Control.Arrow से है, और सिर्फ कार्यों से अधिक पर काम करता है।


>>>में परिभाषित किया गया है Control.Category
स्टीवन शॉ

13

शैली और संस्कृति के अलावा, यह शुद्ध या अशुद्ध कोड के लिए भाषा डिजाइन के अनुकूलन के लिए उबलता है।

|>ऑपरेटर एफ # में आम है बड़े पैमाने पर है क्योंकि यह दो सीमाओं कि मुख्य रूप से-अशुद्ध कोड के साथ दिखाई छिपाने के लिए मदद करता है:

  • संरचनात्मक उपप्रकार के बिना बाएं से दाएं प्रकार का अनुमान।
  • मान प्रतिबंध।

ध्यान दें कि पूर्व सीमा OCaml में मौजूद नहीं है, क्योंकि सबमिशनिंग नाममात्र के बजाय संरचनात्मक है, इसलिए संरचनात्मक प्रकार को आसानी से परिष्कृत किया जाता है क्योंकि प्रकार की अवरोधन प्रगति होती है।

हास्केल एक अलग ट्रेड-ऑफ लेता है, मुख्य रूप से शुद्ध कोड पर ध्यान केंद्रित करने का चयन करता है जहां इन सीमाओं को उठाया जा सकता है।


8

मुझे लगता है कि हैसेल में एफ # के पाइप फॉरवर्ड ऑपरेटर ( |>) बनाम ( और ) चाहिए ।

// pipe operator example in haskell

factorial :: (Eq a, Num a) =>  a -> a
factorial x =
  case x of
    1 -> 1
    _ -> x * factorial (x-1)
// terminal
ghic >> 5 & factorial & show

यदि आपको पसंद नहीं है ( &) ऑपरेटर, तो आप इसे F # या Elixir की तरह कस्टम कर सकते हैं:

(|>) :: a -> (a -> b) -> b
(|>) x f = f x
infixl 1 |>
ghci>> 5 |> factorial |> show

क्यों infixl 1 |>? डेटा-फ़ंक्शन (और) में डॉक्टर देखें

infixl = infix + बाईं सहक्रियाशीलता

infixr = infix + समरूपता


(।)

( .) का अर्थ है कार्य रचना। इसका अर्थ है (fg) (x) = f (g (x)) गणित में।

foo = negate . (*3)
// ouput -3
ghci>> foo 1
// ouput -15
ghci>> foo 5

यह बराबर है

// (1)
foo x = negate (x * 3) 

या

// (2)
foo x = negate $ x * 3 

( $) ऑपरेटर को डेटा-फंक्शन ($) में भी निर्धारित किया जाता है ।

( .) बनाने Hight Order Functionया बनाने के लिए प्रयोग किया जाता है closure in js। उदाहरण देखें:


// (1) use lamda expression to create a Hight Order Function
ghci> map (\x -> negate (abs x)) [5,-3,-6,7,-3,2,-19,24]  
[-5,-3,-6,-7,-3,-2,-19,-24]


// (2) use . operator to create a Hight Order Function
ghci> map (negate . abs) [5,-3,-6,7,-3,2,-19,24]  
[-5,-3,-6,-7,-3,-2,-19,-24]

वाह, कम (कोड) बेहतर है।


तुलना |>और.

ghci> 5 |> factorial |> show

// equals

ghci> (show . factorial) 5 

// equals

ghci> show . factorial $ 5 

यह left —> rightऔर के बीच का अंतर है right —> left। ⊙﹏⊙ |||

मानवीकरण

|>और &से बेहतर है.

इसलिये

ghci> sum (replicate 5 (max 6.7 8.9))

// equals

ghci> 8.9 & max 6.7 & replicate 5 & sum

// equals

ghci> 8.9 |> max 6.7 |> replicate 5 |> sum

// equals

ghci> (sum . replicate 5 . max 6.7) 8.9

// equals

ghci> sum . replicate 5 . max 6.7 $ 8.9

ऑब्जेक्ट ओरिएंटेड भाषा में कार्यात्मक प्रोग्रामिंग कैसे करें?

कृपया http://reactivex.io/ पर जाएं

आईटी समर्थन :

  • जावा: RxJava
  • जावास्क्रिप्ट: आरएक्सजेएस
  • C #: Rx.NET
  • C # (एकता): UniRx
  • स्काला: RxScala
  • क्लोजर: RxClojure
  • C ++: RxCpp
  • Lua: RxLua
  • रूबी: Rx.rb
  • अजगर: आरएक्सपीवाई
  • जाओ: RxGo
  • Groovy: RxGroovy
  • JRuby: RxJRuby
  • कोटलिन: RxKotlin
  • स्विफ्ट: RxSwift
  • PHP: RxPHP
  • अमृत: फिर से
  • डार्ट: आरएक्सडार्ट

1

हास्केल (रस्ट और एफ # के बाद) की कोशिश करने के लिए यह मेरा पहला दिन है, और मैं एफ # 's को परिभाषित करने में सक्षम था।>:

(|>) :: a -> (a -> b) -> b
(|>) x f = f x
infixl 0 |>

और यह काम करने लगता है:

factorial x =
  case x of
    1 -> 1
    _ -> x * factorial (x-1)

main =     
    5 |> factorial |> print

मुझे यकीन है कि एक हास्केल विशेषज्ञ आपको और भी बेहतर समाधान दे सकता है।


1
तुम भी infix ऑपरेटरों को परिभाषित कर सकते हैं infix :) x |> f = f x
जेमी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.