2010-09-06 73 views
9

我最近给Scala的第二次机会,并开始与项目,我始终贯彻执行(功能性或伪函数式语言):一个自动推理的命题逻辑(后来谓词逻辑)。斯卡拉 - 前缀目运算符

现在,我已经试图让命题逻辑的符号语言本身一样漂亮越好,到目前为止,我已经得到了这一点 - 与隐式转换(字符串 - >凌动):

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

功能“与”和“隐含”(和“或”和“等价物”)是调用相关的情况下,类的构造函数的简单方法。然而,在实现时“不”,我被卡住有以下两种符号的:

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

有没有办法来欺骗斯卡拉接受这项期望:

not("A" and "B") 

Preferrably不重新命名类“不”“不”,因为我可能喜欢把它称为“¬”或别的东西,在未来届。

回答

4

截至2014年2月,我认为最简洁的方式定义表达式前缀'not操作,同时避免所有类型的额外cruft/wrapping,将直接在包范围内声明函数,与所有你的其他函数,类,类型等等:这是通过定义一个包对象来完成的(Scala不允许你仅仅把函数放在.scala文件的根目录下(我想知道为什么) Java的脚步?))。

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

(凡Expr应该是的AndOrNotAtom的公共超)

编辑:下面是一个只用一次导入就可以使用的例子:

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

谢谢,我不知道我可以使用Scala的“静态导入” - 这会离开我,每个页面上的强制性进口,虽然,这 - 一起隐式转换对于每次使用都会有很多额外的代码。 – wen 2010-09-06 14:00:02

+2

@Dennetik:如果你只是把所有东西都放到Logic对象中,那么'import logic._'就是你需要使用你的类的所有东西。 – sepp2k 2010-09-06 14:15:17

+1

没想到这一点,我仍然必须习惯Scala的自由,与Java相比... – wen 2010-09-06 14:23:35

19

我注意到this answer来,它似乎是一个可以与unary_前缀运营商的名称才达到你正在尝试做的另一个问题。 (见unary_!

编辑:this article确认语法。

+1

尽管如此,它并不适用于自定义操作符名称。即你不能定义'unary_not'来得到一个前缀“not” - 操作符。 – sepp2k 2010-09-06 12:58:45

+16

具体而言'prefix_'只适用于'!','〜','+'和'-'。 – sepp2k 2010-09-06 13:02:42

+1

@ sepp2k:谢谢,没有意识到这个细节。这个限制看起来有些耻辱(并且完全是任意的)。 – 2010-09-06 13:06:57

8

为什么Not代替not?有没有什么可以阻止你这样做:

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

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

+0

为什么大家总是想方设法使用包对象将函数直接放入包中... – 2014-02-13 02:58:38

+1

@ErikAllik因为2010年没有包对象。 – 2014-02-13 05:32:40

+0

好点!没有意识到 - 谢谢:) P.S.然而,你今天会用一个来定义'not(expr:T)'吗? – 2014-02-13 12:45:25