scala:记住一个函数,无论该函数有多少个参数?
我想在 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 声明(所以不好)的 memoize 方法位于 在 Scala 中使用什么类型来存储内存中的可变数据表?。
i want to write a memoize function in scala that can be applied to any function object no matter what that function object is. i want to do so in a way that lets me use a single implementation of memoize. i'm flexible about the syntax, but ideally the memoize appears somewhere very close to the declaration of the function as opposed to after the function. i'd also like to avoid first declaring the original function and then a second declaration for the memoized version.
so some ideal syntax might be this:
def slowFunction(<some args left intentionally vague>) = memoize {
// the original implementation of slow function
}
or even this would be acceptable:
def slowFUnction = memoize { <some args left intentionally vague> => {
// the original implementation of slow function
}}
i've seen ways to do this where memoize must be redefined for each arity function, but i want to avoid this approach. the reason is that i will need to implement dozens of functions similar to memoize (i.e. other decorators) and it's too much to ask to have to copy each one for each arity function.
one way to do memoize that does require you to repeat memoize declarations (so it's no good) is at What type to use to store an in-memory mutable data table in Scala?.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可以使用类型类方法来处理数量问题。您仍然需要处理您想要支持的每个函数数量,但不是每个数量/装饰器组合:
然后您可以按如下方式实现装饰器:
您的“理想”语法将不起作用,因为编译器会假设该块传入
memoize
的是一个 0 参数的词法闭包。但是,您可以使用后一种语法:编辑:
为了消除定义新装饰器的大量样板,您可以创建一个特征:
这允许您将 Memoize 装饰器重新定义为
而不是调用Memoize 对象上的
memoize
方法,您可以直接应用 Memoize 对象:或者
You can use a type-class approach to deal with the arity issue. You will still need to deal with each function arity you want to support, but not for every arity/decorator combination:
You can then implement the decorator as follows:
Your "ideal" syntax won't work because the compiler would assume that the block passed into
memoize
is a 0-argument lexical closure. You can, however, use your latter syntax:Edit:
To eliminate a lot of the boilerplate for defining new decorators, you can create a trait:
This allows you to redefine the Memoize decorator as
Rather than invoking a
memoize
method on the Memoize object, you apply the Memoize object directly:or
库
使用 Scalaz 的
scalaz.Memo
手册
下面是类似于 Aaron Novstrup 的答案和 此博客,除了一些更正/改进之外,简洁且更容易满足人们的复制和粘贴需求:)
当您运行ExampleMemoize时,您将 得到:
Library
Use Scalaz's
scalaz.Memo
Manual
Below is a solution similar to Aaron Novstrup's answer and this blog, except with some corrections/improvements, brevity and easier for peoples copy and paste needs :)
When you run ExampleMemoize you will get:
我想你可以做这样的事情,而不是使用 DynamicProxy 来实际实现。
我们的想法是,由于函数缺乏通用的超类型,因此我们使用结构类型来查找可以元组的任何内容(Function2-22,您仍然需要特殊情况 Function1)。
我将 Manifest 放在那里,这样您就可以从函数特征构造 DynamicProxy,即 F
元组也应该有助于记忆,就像您简单地将元组放入 Map[T,R] 中一样
I was thinking that you could do something like this and than use a DynamicProxy for the actual implementation.
The idea being that becuase functions lack a common super type we use a structural type to find anything that can be tupled (Function2-22, you still need to special case Function1).
I throw the Manifest in there so you can construct the DynamicProxy from the function trait that is F
Tupling should also help with the memoization as such as you simple put the tuple in a Map[T,R]
这是有效的,因为
K
可以是元组类型,因此memo(x,y,z) { function of x, y, z }
有效:隐式是我的唯一方法可以看到干净地引入地图:
感觉应该可以以某种方式包装自动
HashMap[K,R]
这样你就不必制作fibMap(并重新描述类型)明确地。
This works because
K
can be a tuple type somemo(x,y,z) { function of x, y, z }
works:The implicit was the only way I could see to bring in the map cleanly:
It feels like it should be possible to somehow wrap up an automatic
HashMap[K,R]
so that you don't have to makefibMap
(and re-describe the type) explicitly.