首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >scala中的lambda微积分

scala中的lambda微积分
EN

Stack Overflow用户
提问于 2016-04-22 18:10:40
回答 2查看 1.9K关注 0票数 6

好的,所以我正在尝试实现lambda微积分基础。开始吧。

我的号码:

代码语言:javascript
复制
def zero[Z](s: Z => Z)(z: Z): Z = z
def one[Z](s: Z => Z)(z: Z): Z = s(z)
def two[Z](s: Z => Z)(z: Z): Z = s(s(z))

它们的部分(实际上,非)应用版本是这样的:

代码语言:javascript
复制
def z[Z]: (Z => Z) => (Z => Z) = zero _

在继续之前,我定义了一些类型:

代码语言:javascript
复制
type FZ[Z] = Z => Z
type FFZ[Z] = FZ[Z] => FZ[Z]

好吧,succ函数是这样的(应用程序顺序应该是这样的!我采用了这里的定义):

代码语言:javascript
复制
def succ[Z](w: FFZ[Z])(y: FZ[Z])(x: Z): Z = y((w(y))(x))

它的未应用版本就像:

代码语言:javascript
复制
def s[Z]: FFFZ[Z] = successor _

请原谅,这是缺少的类型:

代码语言:javascript
复制
type FFFZ[Z] = FFZ[Z] => FFZ[Z]
type FFFFZ[Z] = FFFZ[Z] => FFFZ[Z]

但是我被困在add函数上了。如果符合类型和定义(也采用这里 ),则如下所示

代码语言:javascript
复制
def add[Z](a: FFFFZ[Z])(b: FFZ[Z]): FFZ[Z] =
  (a(s))(b)

但是我希望a是一个普通的FFZ[Z]类型。

那么-我该怎么定义加法?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-04-22 20:01:12

在Scala中实现教会数字是完全可能的。以下是这样一个相当直截了当的实现:

代码语言:javascript
复制
object ChurchNumerals {

  type Succ[Z] = Z => Z
  type ChNum[Z] = Succ[Z] => Z => Z

  def zero[Z]: ChNum[Z] =
    (_: Succ[Z]) => (z: Z) => z

  def succ[Z] (num: ChNum[Z]): ChNum[Z] =
    (s: Succ[Z]) => (z: Z) => s( num(s)(z) )

  // a couple of church constants
  def one[Z] : ChNum[Z] = succ(zero)
  def two[Z] : ChNum[Z] = succ(one)

  // the addition function
  def add[Z] (a: ChNum[Z]) (b: ChNum[Z]) =
    (s: Succ[Z]) => (z: Z) => a(s)( b(s)(z) )

  def four[Z] : ChNum[Z] = add(two)(two)

  // test
  def church_to_int (num: ChNum[Int]): Int =
    num((x: Int) => x + 1)(0)

  def fourInt: Int = church_to_int(four)

  def main(args: Array[String]): Unit = {
    println(s"2 + 2 = ${fourInt}")
  }
}

汇编和打印:

代码语言:javascript
复制
$ scala church-numerals.scala
2 + 2 = 4

如果我要从头开始解释教会数字,我会增加更多的评论。但考虑到上下文,我不确定在这种情况下该评论什么。请随便问,我会补充更多的解释。

票数 5
EN

Stack Overflow用户

发布于 2016-04-22 21:15:50

我有编码数字,布尔和对:https://github.com/pedrofurla/church/blob/master/src/main/scala/Church.scala跟随丘奇的风格。

我注意到的一件事是,使用curried函数语法比使用多个参数列表容易得多。一些有趣的片段

代码语言:javascript
复制
type NUM[A] = (A => A) => A => A
def succ  [A]: NUM[A]  =>  NUM[A] = m => n => x => n(m(n)(x))
def zero  [A]: NUM[A] = f => x => x
def one   [A]: NUM[A] = f => x => f(x)
def two   [A]: NUM[A] = f => x => f(f(x))
def three [A]: NUM[A] = f => x => f(f(f(x)))
def plus  [A]: (NUM[A]) => (NUM[A]) => NUM[A] = m => n => f => x => m(f)(n(f)(x))

现在打印出来(非常类似于Antov Trunov的解决方案):

代码语言:javascript
复制
def nvalues[A] = List(zero[A], one[A], two[A], three[A])

val inc: Int => Int  = _ + 1 
def num: (NUM[Int]) => Int = n => n(inc)(0)
def numStr: (NUM[String]) => String = n => n("f (" + _ + ") ")("z")

一些产出:

代码语言:javascript
复制
scala> println(nvalues map num)
List(0, 1, 2, 3)

scala> println(nvalues map numStr) // Like this better :)
List(z, f (z) , f (f (z) ) , f (f (f (z) ) ) )
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36800669

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档