В связи с недавним релизом решил взглянуть чуть пристальнее.
Наткнулся вот на такое:
Y-combinator in Scala
Попробовал для него написать "сферовакуумконя№2" — функцию Аккермана.
(Int) => (Int) => Int получается элементарно:
scala> val ac = Y[Int,Int=>Int](f => m => (n => if (m==0) n+1 else if (n==0) f(m-1)(1) else f(m-1)(f(m)(n-1))))
ac: (Int) => (Int) => Int = <function>
scala> ac(3)(4)
res4: Int = 125
с (Int, Int) => Int уже хуже:
scala> val ack = (Y[Int,Int=>Int](f => m => (n => if (m==0) n+1 else if (n==0) f(m-1)(1) else f(m-1)(f(m)(n-1)))))(_)(_)
<console>:7: error: missing parameter type for expanded function ((x$1, x$2) => Y[Int, scala.Function1[Int, Int]](((f) => ((m) => ((n) => if
(m.$eq$eq(0))
n.$plus(1)
else
if (n.$eq$eq(0))
f(m.$minus(1))(1)
else
f(m.$minus(1))(f(m)(n.$minus(1)))))))(x$1)(x$2))
val ack = (Y[Int,Int=>Int](f => m => (n => if (m==0) n+1 else if (n==0) f(m-1)(1) else f(m-1)(f(m)(n-1)))))(_)(_)
^
<console>:7: error: missing parameter type for expanded function ((x$1: <error>, x$2) => Y[Int, scala.Function1[Int, Int]](((f) => ((m) => (
(n) => if (m.$eq$eq(0))
n.$plus(1)
else
if (n.$eq$eq(0))
f(m.$minus(1))(1)
else
f(m.$minus(1))(f(m)(n.$minus(1)))))))(x$1)(x$2))
val ack = (Y[Int,Int=>Int](f => m => (n => if (m==0) n+1 else if (n==0) f(m-1)(1) else f(m-1)(f(m)(n-1)))))(_)(_)
^
Приходится указывать тип. Почему? Или можно переписать так, что бы он сам таки вывел типы?