F# - 处理类似地图的功能

时间:2014-03-27 11:43:26

标签: map f# functional-programming

长话短说,我想出了这个有趣的功能设置,它需要一个功能, f:'k - > 'v ,选择的值 k:'k ,选择的结果 v:'v ,使用f作为新函数的基础 g:'k - > 'v f 完全相同,除了它现在认为 g k = v

这是为了实现它而编写的(非常简单的)F#代码:

let set : ('k -> 'v) -> 'k -> 'v -> 'k -> 'v = 
    fun f k v x ->
        if x = k then v else f x

我的问题是:

此功能是否会造成任何问题?

我可以想象重复使用这个函数,比如这个

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

将开始在堆上构建一长串函数。这是值得关注的吗?

有没有更好的方法来做到这一点,同时仍保持类型?

我的意思是,我可以做一些事情,比如构建一个用于保存原始函数的类型, f ,一个Map,将键值对设置到地图,以及检查首先是地图,第二个是函数,当使用键来获取值时,但这并不是我感兴趣的东西 - 我感兴趣的是为给定的函数设置了一个“修改”给定值的单个结果的函数。

1 个答案:

答案 0 :(得分:5)

潜在问题:

  1. 如果您重写两次相同的值,set - 修改后的函数会泄漏空间:

    let huge_object = ...
    let small_object = ...
    
    let f0 = set f 0 huge_object
    let f1 = set f0 0 small_object
    

    即使它永远不会是f1的输出,但只有huge_object才能对f1进行垃圾回收:huge_object引用f0,然后由f1引用。

  2. set - 修改后的函数在应用于set的操作数中具有开销线性。

  3. 我不知道这些是否是您预期应用程序的实际问题。

    如果您希望set具有完全类型('k -> 'v) -> 'k -> 'v -> 'k -> 'v,那么我看不到更好的方式(*)。显而易见的想法是拥有一个已经修改过的函数的“修改表”,然后让set在此表中查找给定的f。但是函数类型不允许进行等式检查,因此您无法将f与修改表中已知的函数集进行比较。

    (*)反思不能承受。