2010-09-06 22 views
9

मैंने हाल ही में स्कैला को दूसरा मौका दिया है, और प्रोजेक्ट के साथ शुरू किया है जो मैं हमेशा कार्यान्वित करता हूं (कार्यात्मक या छद्म-कार्यात्मक भाषाओं में): प्रस्तावित तर्क (और बाद में तर्क तर्क) के लिए एक स्वचालित कारण।स्कैला - उपसर्ग यूनरी ऑपरेटर्स

अब, मैं भाषा में ही संभव के रूप में सुंदर में प्रोपोज़िशनल तर्क का अंकन प्राप्त करने की कोशिश की है, और मैं इस अब तक मिल गया है - एक अंतर्निहित रूपांतरण के साथ (स्ट्रिंग -> एटम):

("A" and "B") implies "C" 

फ़ंक्शंस "और" और "तात्पर्य" (और "या" और "समतुल्य") सरल विधियां हैं जो प्रासंगिक केस क्लास कन्स्ट्रक्टर को कॉल करते हैं। हालांकि, जब "नहीं" को लागू करने, मैं अटक दो निम्नलिखित अंकन से किसी के साथ मिलता है: वर्ग का नाम बदलने के बिना

not("A" and "B") 

अधिमानतः:

("A" and "B").not 
Not("A" and "B") 

वहाँ एक रास्ता वांछित को स्वीकार करने में स्काला चाल करने के लिए है "नहीं" से "नहीं", क्योंकि मैं इसे भविष्य में "¬" या कुछ और कह सकता हूं।

उत्तर

4

फरवरी 2014 तक, मुझे लगता है कि एक उपसर्ग 'अभिव्यक्तियों पर ऑपरेशन को परिभाषित करने का सबसे साफ तरीका है, जबकि अतिरिक्त क्रूर/रैपिंग के सभी प्रकार से परहेज करते हुए, कार्य को सीधे पैकेज के दायरे में घोषित करना होगा, साथ ही साथ आपके अन्य कार्यों, वर्गों, प्रकार इत्यादि: यह एक पैकेज ऑब्जेक्ट को परिभाषित करके किया जाता है (स्कैला आपको .scala फ़ाइल के रूट स्तर पर फ़ंक्शंस लगाने की अनुमति नहीं देता है (मुझे यह जानना अच्छा लगेगा कि यह क्यों है जावा के कदम?))।

package org.my.logiclib 

implicit class Atom(s: String) { ... } 
class MyType1 
class MyType2 

object `package` { 
    def not(expr: Expr) = ... 
} 

इस तरह से, import org.my.logiclib._ कर not() सहित सब कुछ आयात करेगा।

ऊपर के रूप में

package org.my 

package logiclib { 
    implicit class Atom ... 
    ... 

    def not(expr: Expr) = ... 
} 
14

आप एक सिंगलटन वस्तु पर एक विधि के रूप not परिभाषित कर सकते हैं इस तरह,:

object Logic { 
    def not(x:Expr) = Not(x) 
} 
import Logic._ 
not("A" and "B") 

संपादित करें (कहाँ ExprAnd, Or, Not और Atom के आम सुपर क्लास माना जाता है) : यहां एक उदाहरण दिया गया है कि इसका उपयोग केवल एक ही आयात के साथ किया जा सकता है:

object Logic { 
    abstract class Expr { 
    def and(e: Expr) = Conjunction(this, e) 
    def or(e: Expr) = Disjunction(this, e) 
    def implies(e: Expr) = Implication(this, e) 
    } 
    case class Conjunction(e1: Expr, e2: Expr) extends Expr 
    case class Disjunction(e1: Expr, e2: Expr) extends Expr 
    case class Implication(e1: Expr, e2: Expr) extends Expr 
    case class Negation(e: Expr) extends Expr 
    case class Atom(name: String) extends Expr 

    def not(e: Expr) = Negation(e) 
    implicit def string2atom(str: String) = Atom(str) 
} 

// use site 
import Logic._ 
not("A" and "B") implies (not("A") or not("B")) 
+0

धन्यवाद एक ही है, मुझे लगता है मैं इस्तेमाल कर सकते हैं "स्थिर आयात" स्काला में नहीं पता था - यह है, हालांकि प्रत्येक पृष्ठ पर एक अनिवार्य आयात के साथ मुझे छोड़ जाएगा, जो - एक साथ अंतर्निहित रूपांतरण प्रत्येक उपयोग के लिए बहुत अधिक कोड होगा। – wen

+2

@ डेनेटिक: यदि आप बस सब कुछ तर्क वस्तु में डाल देते हैं, तो 'Logic._ आयात करें' आपको अपनी कक्षाओं का उपयोग करने की आवश्यकता है। – sepp2k

+1

उस बारे में सोचा नहीं था, मुझे अभी भी जावा की तुलना में स्कैला की आजादी के लिए उपयोग करना होगा ... – wen

19

मैंने this answer पर एक अन्य प्रश्न पर ध्यान दिया कि ऐसा लगता है कि आप ऑपरेटर नाम को unary_ के साथ उपसर्ग कर सकते हैं ताकि आप जो भी करने का प्रयास कर रहे हैं उसे प्राप्त कर सकें। (unary_! देखें।)

संपादित करें: this article वाक्यविन्यास की पुष्टि करता है।

+1

हालांकि यह कस्टम ऑपरेटर नामों के साथ काम नहीं करता है। अर्थात। आप उपसर्ग "नहीं" -ऑपरेटर प्राप्त करने के लिए 'unary_not' को परिभाषित नहीं कर सकते हैं। – sepp2k

+16

विशेष रूप से 'prefix_' केवल'! ',' ~ ',' + 'और' -' के साथ काम करता है। – sepp2k

+1

@ sepp2k: धन्यवाद, इस subtlty का एहसास नहीं था। यह प्रतिबंध थोड़ा शर्म की तरह लगता है (और पूरी तरह से मनमाना)। –

8

not के बजाय क्यों?

object not { 
    def apply(expr: T) = ... 
} 

और फिर not("A" and "B") का उपयोग करें: ऐसा करने से आप को रोकने के लिए कुछ भी नहीं है।

+0

पैकेज ऑब्जेक्ट्स का उपयोग करके सीधे पैकेज में फ़ंक्शंस डालने के तरीकों को हर जगह क्यों ढूंढ रहे हैं ... –

+1

@ErikAllik क्योंकि 2010 में कोई पैकेज ऑब्जेक्ट नहीं था। –

+0

अच्छा बिंदु! इसका एहसास नहीं हुआ- धन्यवाद :) पी एस हालांकि, क्या आप आज 'एक्स (एक्सपीआर: टी)' को परिभाषित करने के लिए उपयोग करेंगे? –