pha*_*haz 5 f# functional-programming map
长话短说,我想出了这个有趣的函数集,它接受一个函数,f:'k - >'v,一个选择的值,k:'k,一个选择的结果,v:'v,用f作为基础对于一个新函数g:'k - >'v与f完全相同,除了它现在认为,gk = v.
这是为了实现它而编写的(非常简单的)F#代码:
let set : ('k -> 'v) -> 'k -> 'v -> 'k -> 'v =
fun f k v x ->
if x = k then v else f x
Run Code Online (Sandbox Code Playgroud)
我的问题是:
这个功能有什么问题吗?
我可以想象重复使用这个功能,就像这样
let kvs : (int * int) List = ... // A very long list of random int pairs.
List.fold (fun f (k,v) -> set f k v) id kvs
Run Code Online (Sandbox Code Playgroud)
将开始在堆上构建一长串函数.这是值得关注的吗?
有没有更好的方法来做到这一点,同时仍然保持类型?
我的意思是,我可以做一些事情,比如构建一个用于保存原始函数的类型,f,一个Map,将键值对设置到地图,然后首先检查地图,第二个函数,当使用键获取值时,但这是这里没有什么让我感兴趣的 - 对于给定的函数,我感兴趣的是具有"修改"给定值的单个结果的功能.
潜在问题:
该set如果重写相同值的两倍修饰功能泄漏空间:
let huge_object = ...
let small_object = ...
let f0 = set f 0 huge_object
let f1 = set f0 0 small_object
Run Code Online (Sandbox Code Playgroud)
即使它永远不能是输出f1,huge_object也不能进行垃圾收集,直到f1可以:huge_object被引用f0,而后者又被引用f1.
修改后的set函数在set应用于它的操作数上具有线性开销.
我不知道这些是否是您预期应用的实际问题.
如果你想set拥有完全相同的类型,('k -> 'v) -> 'k -> 'v -> 'k -> 'v那么我看不到更好的方式(*).显而易见的想法是拥有一个你已经修改过的函数的"修改表",然后在这个表中set查找一个给定的函数f.但是函数类型不允许进行相等性检查,因此您无法与f修改表中已知的函数集进行比较.
(*)反思不然.
| 归档时间: |
|
| 查看次数: |
141 次 |
| 最近记录: |