2012-09-14 35 views
17

在Data.List的分区中使用〜(懒惰模式匹配)有什么性能优势。当一个元组构造函数中的值永远不会被使用时(f(x,y)= 1),延迟模式匹配的受限例子表明它非常有用。在分区(select,below)中,总是使用ts,fs列表(如果应用于x的谓词p为True或不)。我敢肯定,这是一个非常明智的决定,使用〜,但是有什么意义?为什么不严格模式匹配?Data.List中的惰性模式匹配

partition    :: (a -> Bool) -> [a] -> ([a],[a]) 
{-# INLINE partition #-} 
partition p xs = foldr (select p) ([],[]) xs 

select :: (a -> Bool) -> a -> ([a], [a]) -> ([a], [a]) 
select p x ~(ts,fs) | p x  = (x:ts,fs) 
        | otherwise = (ts, x:fs) 

(注:我已经看过here没有回答上面的问题!)

+0

cf. http://en.wikipedia.org/wiki/Tail_call#Tail_recursion_modulo_cons –

回答

17

的一点是,以严格的模式匹配,结果组装只能当月底开始要分区的列表已经达到,特别是partition根本无法用于无限列表。

通过严格的模式匹配,参数必须被评估为WHNF。这意味着尾部的整个foldr必须在决定x是放在第一个还是第二个组件之前完成。

select p x (foldr (select p) ([],[]) (y:z:ws)) 
~> select p x (select p y (select p z (foldr (select p) ([],[]) ws))) 

随着懒惰模式匹配,一对被立即构造,与x作为适当的部件的第一元件,和两个列表的其余部分在需要时在稍后评价。