10

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

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

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

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

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

有没有办法欺骗 Scala 接受所需的:

not("A" and "B")

最好不要将类“Not”重命名为“not”,因为将来我可能会称它为“¬”或其他名称。

4

4 回答 4

22

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

编辑:这篇文章确认了语法。

于 2010-09-06T12:42:32.743 回答
14

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

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

(哪里Expr应该是 , 和 的And公共OrNotAtom

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

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"))
于 2010-09-06T12:35:27.393 回答
8

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

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

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

于 2010-09-06T14:22:34.603 回答
5

截至 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) = ...
}

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

上面是一样的

package org.my

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

  def not(expr: Expr) = ...
}
于 2014-02-13T12:49:33.957 回答