在foldr向Haskell新手解释时,规范定义是
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr _ z [] = z
foldr f z (x:xs) = f x (foldr f z xs)
Run Code Online (Sandbox Code Playgroud)
但在GHC.Base中,foldr定义为
foldr k z = go
where
go [] = z
go (y:ys) = y `k` go ys
Run Code Online (Sandbox Code Playgroud)
看起来这个定义是对速度的优化,但我不明白为什么使用辅助函数go会使它更快.源评论(见这里)提到了内联,但我也没有看到这个定义如何改进内联.
有一段源代码源于对我的另一个问题的回答,
infFromPrefix :: Eq a => ([a] -> [a]) -> [a] -> [a]
infFromPrefix rules prefix = inf where
inf = prefix ++ case stripPrefix prefix (rules inf) of
Just suffix -> suffix
Nothing -> error "Substitution does not preserve prefix"
Run Code Online (Sandbox Code Playgroud)
我在哪里敢肯定,inf一定是一个封闭物,它可以访问来自于它使用传递给参数的意义及其封闭的范围变量infFromPrefix,但由于本质上是不确定infFromPrefix和inf相同的功能,inf只允许一个更简洁的定义.等价的定义是
infFromPrefix rules prefix = prefix ++ case stripPrefix prefix (rules $ infFromPrefix rules prefix) of
Just suffix -> suffix
Nothing -> error "Substitution does not preserve …Run Code Online (Sandbox Code Playgroud)