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
Scala - Prefix Unary Operators
提问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").

