Scala - Prepix Unary Operators
-
01-10-2019 - |
سؤال
لقد أعطيت مؤخراً فرصة ثانية ، وبدأت بالمشروع الذي أقوم بتطبيقه دائمًا (بلغات وظيفية أو وظيفية وظيفية): عقلاني تلقائي للمنطق المقترح (والمنطق الأصلي لاحقًا).
الآن ، حاولت الحصول على تدوين المنطق المقترح باللغة نفسها قدر الإمكان ، وقد وصلت إلى هذا الحد - مع تحويل ضمني (سلسلة -> ذرة):
("A" and "B") implies "C"
تعد الوظائف "و" و "و" و "و" و "و" ما يعادلها ") طرقًا بسيطة تسمي مُنشئ فئة الحالة ذات الصلة. ومع ذلك ، عند تنفيذ "لا" ، فإنني علقت مع أي من التدوينات التالية:
("A" and "B").not
Not("A" and "B")
هل هناك طريقة لخداع سكالا لقبول المطلوب:
not("A" and "B")
من الأفضل بدون إعادة تسمية الفصل "وليس" إلى "لا" ، لأنني قد أرغب في تسميته "" "أو أي شيء آخر ، في المستقبل.
المحلول
اعتبارًا من فبراير 2014 ، أعتقد أن أنظف طريقة لتحديد بادئة not
ستكون العملية على التعبيرات ، مع تجنب جميع أنواع الرصيف/الالتفاف الإضافي ، هي إعلان الوظيفة مباشرة في نطاق الحزمة ، إلى جانب جميع وظائفك ، والطبقات ، والأنواع ، وما إلى ذلك: يتم ذلك عن طريق تحديد كائن الحزمة (Scala لا " ر فقط تسمح لك بوضع الوظائف على مستوى جذر .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) = ...
}
نصائح أخرى
لقد لاحظت هذا الجواب إلى سؤال آخر يبدو أنه يمكن للمرء أن يبدل اسم المشغل به unary_
لتحقيق ما تحاول القيام به. (نرى unary_!
.)
يحرر: هذه المقالة يؤكد بناء الجملة.
يمكنك تحديد not
كطريقة على كائن مفردة ، مثل هذا:
object Logic {
def not(x:Expr) = Not(x)
}
import Logic._
not("A" and "B")
(أين Expr
من المفترض أن تكون الفئة الشائعة And
, 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"))
لماذا Not
بدلاً من not
؟ لا يوجد شيء يمنعك من القيام بذلك:
object not {
def apply(expr: T) = ...
}
ثم استخدم not("A" and "B")
.