Haskell 惰性评估实现

Haskell 惰性评估实现,haskell,lazy-evaluation,Haskell,Lazy Evaluation,我有一个函数fromRange,它接受一个过滤函数和一个区间,并返回一个集合,其中区间中的所有元素都满足过滤函数 我使用列表理解实现了它: fromRange :: (Integer->Bool) -> (Integer,Integer) -> [Integer] fromRange f (x,y) = [i | i<-[x..y], f i] 但是使用大列表需要很长时间,所以我找到了延迟评估概念,但我不知道如何准确地实现它,有什么帮助吗???对于大型数据集,延迟

我有一个函数fromRange,它接受一个过滤函数和一个区间,并返回一个集合,其中区间中的所有元素都满足过滤函数

我使用列表理解实现了它:

fromRange   :: (Integer->Bool) -> (Integer,Integer)  -> [Integer]
fromRange f (x,y) = [i | i<-[x..y], f i]

但是使用大列表需要很长时间,所以我找到了延迟评估概念,但我不知道如何准确地实现它,有什么帮助吗???

对于大型数据集,延迟评估不应该更快,它只会将评估推迟到需要值的那一刻。例如,如果键入ghci:

在它遍历整个列表以过滤它并打印结果之前,您必须永远等待

另一方面:

take 10 $ fromRange (< 50) (1, 1000000000)
将立即完成,因为它不必计算列表的其余部分


注意:take 100也将挂起,因为它永远找不到足够的条目。

对于大型数据集,延迟计算不应该更快,它只会将计算推迟到需要该值的时刻。例如,如果键入ghci:

在它遍历整个列表以过滤它并打印结果之前,您必须永远等待

另一方面:

take 10 $ fromRange (< 50) (1, 1000000000)
将立即完成,因为它不必计算列表的其余部分


注意:take 100也会挂起,因为它永远找不到足够的条目。

您是否还会添加使用该函数的上下文,以使其变慢?fromRange基本上应该是免费的,因为它只会创建一个thunk。您如何使用它,从而强制评估?另请注意,一个更甜的定义应该是fromRange f x,y=filter f[x..y],此时您最好忘记它,只在任何地方使用filter[a..b]。@bereal例如fromRange odd 11000000000,您如何将其称为fromRange odd 11000000000?在GHCi的提示下?如果是这样,这将强制整个列表以打印它。但是,如果你从Range奇数11000000000中拨出head$,你会立即拿回1。这就是懒惰的意思。您是否也会添加使用函数的上下文,使其速度变慢?fromRange基本上应该是免费的,因为它只会创建一个thunk。您如何使用它,从而强制评估?另请注意,一个更甜的定义应该是fromRange f x,y=filter f[x..y],此时您最好忘记它,只在任何地方使用filter[a..b]。@bereal例如fromRange odd 11000000000,您如何将其称为fromRange odd 11000000000?在GHCi的提示下?如果是这样,这将强制整个列表以打印它。但是,如果你从Range奇数11000000000中拨出head$,你会立即拿回1。这就是懒惰的意思。所以懒惰是为了得到我所需要的,而不去评估其余的。我明白你的意思吗correctly@user1837422:确切地说,你只得到你所需要的,而不是直到你需要的时候,在你的情况下,控制台输出。但如果我只需要最后一个元素,我必须等到它是finished@user1837422对懒惰的评估不能帮助这一点。如果您想从任意列表的末尾获取某些内容,则必须迭代到结尾,然后再考虑斐波那契序列。@user1837422或者您必须更改算法:last$filter f[x..y]==head$filter f[y..x]。要小心这是否真的是一种改进,就像这个答案中的代码示例一样,如果你不得不更深入地重新安排和优化它,那么懒惰的人就是为了得到我需要的,而不评估其余的我明白吗correctly@user1837422:没错,你只会得到你需要的东西,直到你需要的时候才会得到,但是,如果我只需要最后一个元素,我就必须等到它完成后再做呢finished@user1837422是的,懒惰的评估没办法。如果您想从任意列表的末尾获取某些内容,则必须迭代到结尾,然后再考虑斐波那契序列。@user1837422或者您必须更改算法:last$filter f[x..y]==head$filter f[y..x]。要小心这是否真的是一种改进,就像这个答案中的代码示例一样,如果您需要更深入地重新排列和优化它,那么就需要更加小心。