scala:memoize一个函数,无论函数需要多少参数?
发布时间:2020-12-16 09:29:51 所属栏目:安全 来源:网络整理
导读:我想在Scala中写一个memoize函数,无论函数对象是什么,都可以应用于任何函数对象。我想这样做,让我使用单一的memoize实现。我对语法很灵活,但理想情况下,memoize出现在非常接近功能声明的地方,而不是后面的函数。我也想避免首先声明原来的功能,然后是
我想在Scala中写一个memoize函数,无论函数对象是什么,都可以应用于任何函数对象。我想这样做,让我使用单一的memoize实现。我对语法很灵活,但理想情况下,memoize出现在非常接近功能声明的地方,而不是后面的函数。我也想避免首先声明原来的功能,然后是第二个声明为记忆版本。
所以一些理想的语法可能是这样的: def slowFunction(<some args left intentionally vague>) = memoize { // the original implementation of slow function } 甚至这是可以接受的: def slowFUnction = memoize { <some args left intentionally vague> => { // the original implementation of slow function }} 我已经看到了这样做的方式,每个arity功能必须重新定义memoize,但是我想避免这种方法。原因是我需要实现类似于memoize的功能(即其他装饰器),并且要求每个arity功能都要复制每个功能太多了。 一个方法做回忆,这需要你重复memoize声明(所以不好)是在In Scala 2.8,what type to use to store an in-memory mutable data table?。 解决方法
您可以使用类型类方法来处理可靠性问题。您仍然需要处理您想要支持的每个功能,但不是为了每个arity / decorator组合:
/** * A type class that can tuple and untuple function types. * @param [U] an untupled function type * @param [T] a tupled function type */ sealed class Tupler[U,T](val tupled: U => T,val untupled: T => U) object Tupler { implicit def function0[R]: Tupler[() => R,Unit => R] = new Tupler((f: () => R) => (_: Unit) => f(),(f: Unit => R) => () => f(())) implicit def function1[T,R]: Tupler[T => R,T => R] = new Tupler(identity,identity) implicit def function2[T1,T2,R]: Tupler[(T1,T2) => R,((T1,T2)) => R] = new Tupler(_.tupled,Function.untupled[T1,R]) // ... more tuplers } 然后可以按如下方式实现装饰器: /** * A memoized unary function. * * @param f A unary function to memoize * @param [T] the argument type * @param [R] the return type */ class Memoize1[-T,+R](f: T => R) extends (T => R) { // memoization implementation } object Memoize { /** * Memoize a function. * * @param f the function to memoize */ def memoize[T,R,F](f: F)(implicit e: Tupler[F,T => R]): F = e.untupled(new Memoize1(e.tupled(f))) } 您的“理想”语法将不起作用,因为编译器会假定传入memoize的块是一个0参数的词法闭包。但是,您可以使用以下语法: // edit: this was originally (and incorrectly) a def lazy val slowFn = memoize { (n: Int) => // compute the prime decomposition of n } 编辑: 为了消除大量用于定义新装饰器的样板,您可以创建一个特征: trait FunctionDecorator { final def apply[T,T => R]): F = e.untupled(decorate(e.tupled(f))) protected def decorate[T,R](f: T => R): T => R } 这允许您重新定义Memoize装饰器 object Memoize extends FunctionDecorator { /** * Memoize a function. * * @param f the function to memoize */ protected def decorate[T,R](f: T => R) = new Memoize1(f) } 不要在Memoize对象上调用memoize方法,而是直接应用Memoize对象: // edit: this was originally (and incorrectly) a def lazy val slowFn = Memoize(primeDecomposition _) 要么 lazy val slowFn = Memoize { (n: Int) => // compute the prime decomposition of n } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容