Scala中Lambda演算中的布尔逻辑

时间:2018-06-21 08:14:28

标签: scala types functional-programming lambda-calculus

我正在尝试在Scala的lambda演算中实现基本的布尔逻辑,但我始终处于起步阶段。

我有两种类型:

type λ_T[T] = T => T

type λ_λ_T[T] = λ_T[T] => T => T

“ false”效果很好:

def λfalse[T]: λ_λ_T[T] = (s: λ_T[T]) => (z: T) => z

但是当我尝试实现'true'时(如lambda微积分的数学背景中给出的那样),我得到了错误的类型:

def λtrue[T]: λ_λ_T[T] = (s: λ_T[T]) => (z: T) => s

结果错误:类型λ_T[T]的表达与预期的类型T不符

我该如何实现?

1 个答案:

答案 0 :(得分:3)

布尔型is of type的教堂编码

[X] => X -> X -> X

其中[X] =>表示X -> X -> X部分在X中是多态的。

这里有两个建议,您可以在Scala中表达这一点。


布尔值作为通用方法,在呼叫站点键入推论

这里是一种适用于布尔值的类型,在布尔值中可以直接在调用站点上推断所需的多态类型参数:

type B[X] = X => X => X

以下是truefalse的定义,以及一些操作:

def churchTrue[X]: B[X] = a => b => a
def churchFalse[X]: B[X] = a => b => b
def ifThenElse[X](b: B[X], thenResult: X, elseResult: X) = 
  b(thenResult)(elseResult)

def and[X](a: B[B[X]], b: B[X]): B[X] = a(b)(churchFalse)
def or[X](a: B[B[X]], b: B[X]): B[X] = a(churchTrue)(b)
def not[X](a: B[B[X]]) = a(churchFalse)(churchTrue)

示例:

println("t & t = " + and[String](churchTrue, churchTrue)("t")("f"))
println("t & f = " + and[String](churchTrue, churchFalse)("t")("f"))
println("f & t = " + and[String](churchFalse,churchTrue)("t")("f"))
println("f & f = " + and[String](churchFalse,churchFalse)("t")("f"))

请注意,这不允许您表达“ Church-Boolean per-se”的概念,因为它需要固定类型的参数才能应用(上面示例中的String )。尝试从一个特定的调用站点提取表达式并将其移到其他位置时,您必须重新调整所有类型参数,这很烦人。


布尔的真正多态教堂编码

如果要将真正的多态函数表示为一类对象,则必须定义特征或抽象类。对于布尔值,这就像

trait B {
  def apply[X](trueCase: X, elseCase: X): X
}

请注意,现在apply方法在X中是多态的。这使您可以将布尔型的Church编码实现为可传递的一流对象(从方法返回,保存在列表中等):

trait B { self =>
  def apply[X](thenCase: X, elseCase: X): X
  def |(other: B): B = new B { 
    def apply[A](t: A, e: A) = self(True, other)(t, e) 
  }
  def &(other: B): B = new B { 
    def apply[A](t: A, e: A) = self(other, False)(t, e) 
  }
  def unary_~ : B = self(False, True)
}

object True extends B { def apply[X](a: X, b: X) = a }
object False extends B { def apply[X](a: X, b: X) = b }

这里是将其应用于某些实际值的方法:

def toBoolean(b: B): Boolean = b(true, false)

上面的行将调用apply[Boolean](...)

一个例子:

println("And: ")
println(toBoolean(True & True))
println(toBoolean(True & False))
println(toBoolean(False & True))
println(toBoolean(False & False))

println("Or:")
println(toBoolean(True | True))
println(toBoolean(True | False))
println(toBoolean(False | True))
println(toBoolean(False | False))  

println("Funny expresssion that should be `true`:")
println(toBoolean((False | True) & (True & ~False)))

打印:

And: 
  true
  false
  false
  false
Or:
  true
  true
  true
  false
Funny expresssion that should be `true`:
  true