2016-03-23 10 views
7

मैं डॉन सायमे द्वारा एक presentation जो दिखाता है कि Erlang केएफ # में Erlang नए सिरे से लिखना

fac(0) -> 1 
fac(N) -> N * fac(N-1). 

एफ # के

let rec fac = function 
| 0 -> 1 
| n -> n * fac (n-1) 

के बराबर है पाया है लेकिन ऐसा लगता है कि वहाँ पैटर्न के लिए मिलान का उपयोग करने के कोई रास्ता नहीं है की तरह प्रकार की सुरक्षा खोने के बिना एक अलग धर्मार्थ। जैसे एक एक सूची पैटर्न मिलान का उपयोग कर सकता है, लेकिन फिर एक प्रकार होना चाहिए (जैसे object के रूप में) एक आम आधार प्रकार:

let concat = function 
    | [x;y] -> x.ToString() + y.ToString() 
    | [x] -> x.ToString() 

यह देखते हुए कि मॉड्यूल में एफ # कार्यों भार के समर्थन नहीं करते, यह एक ही रास्ता के पुनर्लेखन के लिए की तरह लग रहा स्थैतिक टाइपिंग के साथ एफ # में एरलांग कोड मॉड्यूल के बजाए विधि अधिभार के साथ स्थैतिक वर्गों का उपयोग करना है। क्या एफ # में अलग-अलग धैर्य के साथ एरलांग कार्यों को फिर से लिखने का एक बेहतर तरीका है?

सामान्यतः, क्या यह कहना सही है कि Erlang का तर्क मिलान F # के पैटर्न मिलान के बजाय .NET की (सी # सहित) ओवरलोडिंग के करीब है? या दोनों के बीच कोई प्रत्यक्ष प्रतिस्थापन नहीं है, उदा।

max(x) -> x. 
max(x,y) when x > y -> x. 
max(x,y) -> y. 
max(comparer, x, y) -> if comparer(x,y) > 0 -> x; true -> y end. 

पिछले मामले में तर्क अलग अलग प्रकार के होते हैं: विभिन्न arities + एक गार्ड के साथ Erlang में एक समारोह हो सकता है। आप इसे एफ # में कैसे लिखेंगे?

उत्तर

7

आप समस्या को फिर से सोचकर ओवरलोडिंग के करीब कुछ हासिल कर सकते हैं। भिन्नता की धुरी के रूप में फ़ंक्शन के बारे में सोचने के बजाय, इनपुट को चर के भाग के रूप में सोचें। यदि आप ऐसा करते हैं, तो आपको पता चलेगा कि आप achieve the same with a discriminated union कर सकते हैं।

यहाँ जुड़े हुए लेख में की तुलना में एक अधिक काल्पनिक उदाहरण है:

type MyArguments = One of int | Two of int * int 

let foo = function 
    | One x -> string x 
    | Two (x, y) -> sprintf "%i%i" x y 

उपयोग:

> foo (One 42);; 
val it : string = "42" 
> foo (Two (13, 37));; 
val it : string = "1337" 

जाहिर है, बजाय ऊपर MyArguments के रूप में इस तरह के एक 'बेवकूफ' प्रकार को परिभाषित करने की है, तो आप डी एक भेदभाव संघ को परिभाषित करता है जो आपके द्वारा मॉडलिंग किए जा रहे डोमेन में समझ में आता है।

+0

यह अच्छा है, यह गार्ड का उपयोग करने की अनुमति देता है: 'दो (x, y) जब x> y'। लेकिन अगर कुछ तर्क सिर्फ वैकल्पिक हैं, तो मैं मामलों का नाम देने के लिए संघर्ष कर रहा हूं: उदा। डिफ़ॉल्ट, DefaultWithComparer, ... मुझे पैरामीटर के प्रत्येक संयोजन को नाम देने की आवश्यकता है, जो कुछ हद तक अजीब लगता है। –

+2

@ वी.बी. आप अक्सर अपने इनपुट प्रकार के डिफ़ॉल्ट मान बनाकर डिफ़ॉल्ट को नियंत्रित कर सकते हैं। आपको इसे एक विशेष मामला बनाने की ज़रूरत नहीं है। उदाहरण के तौर पर, यदि आपका फ़ंक्शन * हमेशा * तुलनाकर्ता की आवश्यकता है, तो तुलनाकर्ता को इनपुट प्रकार का एक अनिवार्य फ़ील्ड बनाएं, लेकिन उसके बाद उस इनपुट प्रकार का डिफ़ॉल्ट मान दें जिसमें डिफ़ॉल्ट तुलनात्मक, या वैकल्पिक है, * फ़ंक्शन * जो डिफ़ॉल्ट तुलनाकर्ता के साथ इनपुट मान बनाता है। –

+0

असल में, कमजोरी के बजाय मैंने पिछली टिप्पणी में सोचा था, यह एक तरह की ताकत है: संदेश पासिंग एरलांग के लिए केंद्रीय है, और कोई संदेश के नाम के रूप में प्रत्येक डीयू मामले के बारे में सोच सकता है। प्रत्येक संदेश का अपना तार प्रारूप होता है, आदि संदेशों का स्पष्ट नामकरण - भले ही वर्बोज़ - विकास/प्रोटोटाइप चरण में पठनीयता को जोड़ सके। फिर इसे डीयू ऑब्जेक्ट आवंटन और क्रमबद्धता से बचने के लिए ब्लिटेबल structs के साथ प्रतिस्थापित किया जा सकता है। –

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