मैं निम्नलिखित भेदभाव संघ को परिभाषित किया है:प्रकार विस्तार
let rec stringify expr =
match expr with
| Con(x) -> string x
| Var(x) -> string x
| Add(x, y) -> sprintf "(%s + %s)" (stringify x) (stringify y)
| Sub(x, y) -> sprintf "(%s - %s)" (stringify x) (stringify y)
| Mult(x, y) -> sprintf "(%s * %s)" (stringify x) (stringify y)
| Div(x, y) -> sprintf "(%s/%s)" (stringify x) (stringify y)
| Pow(x, y) -> sprintf "(%s ** %s)" (stringify x) (stringify y)
अब मैं अपने Expr
बनाना चाहते:
type Expr =
| Con of Num
| Var of Name
| Add of Expr * Expr
| Sub of Expr * Expr
| Mult of Expr * Expr
| Div of Expr * Expr
| Pow of Expr * Expr
तब मैं इस प्रकार एक बहुत मुद्रण समारोह बनाया इस फ़ंक्शन का उपयोग अपने ToString()
विधि के लिए करें। उदाहरण के लिए:
type Expr =
| Con of Num
| Var of Name
| Add of Expr * Expr
| Sub of Expr * Expr
| Mult of Expr * Expr
| Div of Expr * Expr
| Pow of Expr * Expr
override this.ToString() = stringify this
लेकिन मैं ऐसा नहीं कर सकते, क्योंकि stringify
अभी तक परिभाषित नहीं है। जवाब Stringify
को Expr
के सदस्य के रूप में परिभाषित करना है, लेकिन मैं समय के साथ बढ़ते रहने के लिए इस विशेष विधि के साथ अपनी प्रारंभिक प्रकार की घोषणा को प्रदूषित नहीं करना चाहता हूं। इसलिए, मैंने एक अमूर्त विधि का उपयोग करने का निर्णय लिया जिसे मैं फ़ाइल में intrinsic type extension के साथ कार्यान्वित कर सकता हूं। यहाँ मैं क्या किया है:
type Expr =
| Con of Num
| Var of Name
| Add of Expr * Expr
| Sub of Expr * Expr
| Mult of Expr * Expr
| Div of Expr * Expr
| Pow of Expr * Expr
override this.ToString() = this.Stringify()
abstract member Stringify : unit -> string
लेकिन मैं निम्नलिखित संकलक त्रुटि मिलती है:
error FS0912: This declaration element is not permitted in an augmentation
संदेश भी सही नहीं प्रतीत होता है (मैं अभी तक एक प्रकार वृद्धि बनाने नहीं कर रहा हूँ), लेकिन मैं समझता हूँ यह शिकायत क्यों कर रहा है। यह नहीं चाहता कि मैं एक भेदभावपूर्ण संघ के प्रकार पर एक अमूर्त सदस्य बनाना चाहता हूं क्योंकि इसे विरासत में नहीं लिया जा सकता है। भले ही मैं वास्तव में विरासत नहीं चाहता हूं, मैं चाहता हूं कि यह सी # में आंशिक वर्ग की तरह व्यवहार करे, जहां मैं इसे कहीं और परिभाषित कर सकता हूं (इस मामले में एक ही फाइल)।
मैं sprintf
के साथ StructuredFormatDisplay
विशेषता के देर से बाध्यकारी शक्ति का उपयोग करके "धोखा दे" समाप्त हो गया:
[<StructuredFormatDisplay("{DisplayValue}")>]
type Expr =
| Con of Num
| Var of Name
| Add of Expr * Expr
| Sub of Expr * Expr
| Mult of Expr * Expr
| Div of Expr * Expr
| Pow of Expr * Expr
override this.ToString() = sprintf "%A" this
/* stringify function goes here */
type Expr with
member public this.DisplayValue = stringify this
अब हालांकि sprintf
और ToString
दोनों उत्पादन एक ही स्ट्रिंग, और वहाँ पाने के लिए कोई रास्ता नहीं है Add (Con 2,Con 3)
आउटपुट के रूप में (2 + 3)
के विपरीत अगर मैं इसे चाहता हूं।
तो क्या ऐसा करने का कोई और तरीका है जो मैं करने की कोशिश कर रहा हूं?
पीएस मैंने यह भी देखा कि यदि मैं मूल प्रकार के बजाय संवर्धन पर StructuredFormatDisplay
विशेषता रखता हूं, तो यह काम नहीं करता है। यह व्यवहार मेरे लिए सही प्रतीत नहीं होता है। ऐसा लगता है कि या तो एफ # कंपाइलर टाइप प्रकार परिभाषा में विशेषता जोड़ना चाहिए या प्रकार संवर्धन पर गुणों को अस्वीकार करना चाहिए।
मुझे लगता है कि मैं इसे स्वीकार करूंगा, भले ही मैं इसका उपयोग नहीं कर सकता क्योंकि यह कम से कम एक तकनीक है जिस पर मैंने विचार नहीं किया था। – luksan