Scala - 前缀一元运算符

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3651404/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 02:25:04  来源:igfitidea点击:

Scala - Prefix Unary Operators

scalalogicnotationunary-operator

提问by wen

I've recently given Scala a second chance, and started with the project I always implement (in functional or pseudo-functional languages): an automated reasoner for propositional logic (and later predicate logic).

我最近给了 Scala 第二次机会,并从我一直在实现的项目开始(使用函数式或伪函数式语言):命题逻辑(以及后来的谓词逻辑)的自动推理器。

Now, I've tried to get the notation of propositional logic in the language itself as pretty as possible, and I've gotten this far - with an implicit conversion (String -> Atom):

现在,我试图在语言本身中获得尽可能漂亮的命题逻辑符号,并且我已经做到了这一点 - 使用隐式转换(字符串 - > Atom):

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

The functions "and" and "implies" (and "or" and "equivalent") are simple methods that call the relevant case class constructor. However, when implementing "not", I get stuck with either of the two following notations:

函数“and”和“implies”(以及“or”和“equivalent”)是调用相关案例类构造函数的简单方法。但是,在实现“not”时,我会遇到以下两种符号中的任何一种:

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

Is there a way to trick Scala into accepting the desired:

有没有办法诱使 Scala 接受所需的内容:

not("A" and "B")

Preferrably without renaming the class "Not" to "not", because I might like to call it "?" or something else, in th future.

最好不要将类“Not”重命名为“not”,因为我可能喜欢称它为“?” 或其他东西,在未来。

采纳答案by Erik Kaplun

As of Feb 2014, I think the cleanest way to define a prefix'ish notoperation on expressions, while avoiding all sorts of extra cruft/wrapping, would be to declare the function directly in the package scope, together with all your other functions, classes, types etc: This is done by defining a package object (Scala doesn't allow you to just put functions at the root level of the .scalafile (I'd love to learn why—is it just to follow Java's footsteps?)).

截至 2014 年 2 月,我认为not在表达式上定义前缀操作的最简洁方法是在包范围内直接声明函数,以及所有其他函数、类、类型等:这是通过定义一个包对象来完成的(Scala 不允许你只将函数放在.scala文件的根级别(我很想知道为什么——它只是跟随 Java 的脚步吗?))。

package org.my.logiclib

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

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

this way, doing import org.my.logiclib._will import everything, including not().

这样,doingimport org.my.logiclib._将导入所有内容,包括not().

The above is the same as

上面是一样的

package org.my

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

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

回答by Paul Ruane

I noticed on this answerto another question that it appears that one can prefix the operator name with unary_to achive what you are trying to do. (See unary_!.)

我注意到在另一个问题的这个答案中,似乎可以在操作员名称前加上前缀unary_来实现您要执行的操作。(见unary_!。)

Edit: this articleconfirms the syntax.

编辑:本文确认了语法。

回答by sepp2k

You can define notas a method on a singleton object, like this:

您可以not在单例对象上定义为方法,如下所示:

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

(Where Expris supposed to be the common superclass of And, Or, Notand Atom)

(哪里Expr应该是And, Or,Not和的公共超类Atom

Edit: Here's an example of how this could be used with only a single import:

编辑:这是一个如何仅通过单个导入使用的示例:

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"))

回答by Daniel C. Sobral

Why Notinstead of not? There's nothing to stop you from doing this:

为什么Not而不是not?没有什么可以阻止你这样做:

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

And then use not("A" and "B").

然后使用not("A" and "B").