2014-09-29 5 views
6

मेरे पास अक्सर एक ही प्रकार के एकाधिक पैरामीटर के साथ एक फ़ंक्शन होता है, और कभी-कभी उन्हें गलत क्रम में उपयोग किया जाता है। एक साधारण उदाहरण के रूप मेंएफ # प्रेत प्रकार

let combinePath (path : string) (fileName : string) = ... 

ऐसा लगता है कि प्रेत प्रकार किसी मिश्रण मिश्रण को पकड़ने का एक अच्छा तरीका होगा। लेकिन मुझे समझ में नहीं आता कि उदाहरण को केवल F# phantom types question में कैसे लागू करें।

मैं इस उदाहरण में प्रेत प्रकार कैसे कार्यान्वित करूं? मैं combinePath कैसे कॉल करूं? या क्या मुझे समस्या का एक आसान समाधान याद आ रहा है?

उत्तर

12

मुझे लगता है कि सबसे आसान तरीका है भेदभाव यूनियनों उपयोग करने के लिए है:

type Path = Path of string 
type Fname = Fname of string 
let combinePath (Path(p)) (Fname(file)) = System.IO.Path.Combine(p, file) 

आप इसे इस तरह

combinePath (Path(@"C:\temp")) (Fname("temp.txt")) 
+5

उन के बाद से कर रहे हैं एक मामले दस, आप भी 'combinePath (पथ (पी)) (fName (च)) = ...', अंत दे सकता हूँ कर सकते हैं -result वही होगा :) –

+0

हां। यह आसान होगा। अद्यतन पोस्ट, धन्यवाद! – Petr

+0

इसका मतलब प्रत्येक पैरामीटर प्रकार के लिए एक प्रकार घोषित करना होगा। मुझे लगता है कि मैं सोच रहा था कि यह माप की इकाइयों की तरह हो सकता है, स्ट्रिंग स्ट्रिंग । यद्यपि इसे अभी भी पथ और फ़ाइल नाम के लिए प्रकारों की आवश्यकता होगी, इसलिए अंत में यह वही है ... मेरे अपने बिंदु का जवाब मुझे लगता है। –

7

मैं पेट्र के टेक से सहमत कह सकते हैं, लेकिन पूर्णता के लिए, ध्यान दें कि आप कर सकते हैं प्रेत प्रकारों का उपयोग करें जब आपके पास उनका उपयोग करने के लिए एक सामान्य प्रकार है ताकि आप सादे string इनपुट के साथ कुछ भी नहीं कर सकें। इसके बजाय, आप कुछ इस तरह कर सकता है:

type safeString<'a> = { value : string } 

type Path = class end 
type FileName = class end 

let combinePath (path:safeString<Path>) (filename:safeString<FileName>) = ... 

let myPath : safeString<Path> = { value = "C:\\SomeDir\\" } 
let myFile : safeString<FileName> = { value = "MyDocument.txt" } 

// works 
let combined = combinePath myPath myFile 

// compile-time failure 
let combined' = combinePath myFile myPath 
+0

स्पष्ट रूप से भेदभाव करने वाला संघ ऐसा करने का बेहतर तरीका है। Fantom प्रकार F # के लिए अनावश्यक प्रतीत होता है। मुझे लगता है कि यही कारण है कि इसमें ज्यादा कवरेज नहीं है। –

+0

@FsharpPete - मुझे नहीं लगता कि यह काफी सही है; इस विशेष परिदृश्य में डीयू बेहतर हो सकते हैं, लेकिन निश्चित रूप से ऐसे परिदृश्य हैं जहां प्रेत प्रकार उपयोगी होते हैं (और मुझे नहीं लगता कि एफ # एक तकनीक या दूसरे का उपयोग करने के मामले में अन्य भाषाओं से काफी अलग है)। – kvb

+0

हां, अब मैं इसे देखता हूं। प्रेत प्रकार के दृष्टिकोण के साथ आप मॉड्यूल/पैकेज के बाहर से प्रेत प्रकार निर्दिष्ट कर सकते हैं, भले ही भेदभाव वाले संघ के साथ। –

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