改变功能的功能的性能

时间:2013-10-21 16:18:37

标签: haskell

假设我们有一个功能

type Func = Bool -> SophisticatedData
fun1 :: Func

我们想要改变这个函数的一些输入:

change :: SophisticatedData -> Func -> Func
change data func = \input -> if input == False then data else func input

我是否正确,在多次调用changeendFunc = change data1 $ change data2 $ startFunc)后,每次调用所有中间函数?我是否正确,GC无法删除未使用的数据?什么是haskell应对这项任务的方式?

感谢。

2 个答案:

答案 0 :(得分:3)

让我们从清理变化开始变得更加清晰

change sd f input = if input then func input else sd

所以当我们撰写这些

change d1 $ change d2 $ change d3

GHC首先为每个人存储一个thunk。请记住,$是一个函数,因此整个change d*事物最初将成为一个thunk。 Thunks相对便宜,如果你不是马上创造10k左右,你就可以了:)所以不用担心。

现在的问题是,当你开始评估时会发生什么,答案是,它仍然不会评估复杂的数据,因此它仍然具有很高的内存效率,而且只需要强制input来确定分支它正在采取。因此,在选择运行并向您返回一个之前,您永远不应该实际完全评估SophisticatedData,如果您使用它,它将被评估为需要。

此外,在每一步中,GHC都可以垃圾收集不需要的thunk,因为它们不再被引用。

总之,你应该没问题。相信懒惰

答案 1 :(得分:1)

你是对的:如果foo是对change的O(n)个调用链,那么每次调用foo都会有O(n)开销。处理此问题的方法是记住foo

memoize :: Func -> Func
memoize f = \x -> if x then fTrue else fFalse where
    fTrue  = f True
    fFalse = f False