For arbitrary nested arrays you can use "deep" implicit conversion with type gymnastics
trait ToIdxFunction[X[_], A] {
type Result
def toIdx(x: X[A]): Int => Result
}
trait LowerPriorityDeepFunctor {
implicit def plainArray[A] =
new ToIdxFunction[Array, A] {
type Result = A
def toIdx(x: Array[A]): Int => Result = {
i => x(i)
}
}
}
object ToIdxFunction extends LowerPriorityDeepFunctor {
implicit def nestedArray[A](implicit inner: ToIdxFunction[Array, A]) = {
new ToIdxFunction[Array, Array[A]] {
type Result = Int => inner.Result
def toIdx(x: Array[Array[A]]): Int => Result = {
i => inner.toIdx(x(i))
}
}
}
}
import ToIdxFunction._
implicit class Ops[X[_], A](self: X[A]) {
def asFunction(implicit F: ToIdxFunction[X, A]) = F.toIdx(self)
}
Example in scala console
scala> Array(1).asFunction
res4: Int => Int = <function1>
scala> Array(Array(1)).asFunction
res5: Int => (Int => Int) = <function1>
scala>
scala> Array(Array(Array(1))).asFunction
res6: Int => (Int => (Int => Int)) = <function1>
scala> Array(Array(Array(Array(1)))).asFunction
res7: Int => (Int => (Int => (Int => Int))) = <function1>
This works:
def foo(f: Int => Int => Int => Int) = println(f(0)(0)(0))
foo(Array(Array(Array(1))).asFunction)
foo1case works because theArraygets implicitly converted into aWrappedArray, which extendsFunction[Int, _]. The other doesn't for a couple of reasons: the conversion won't apply to the inner arrays, andWrappedArrayisn't covariant, so even if the conversion did apply,WrappedArray[WrappedArray[Int]]doesn't extendWrappedArray[Int => Int].