Haskell GHC splitAt性能
splitAt在GHC中的实现方式如下:Haskell GHC splitAt性能,haskell,ghc,Haskell,Ghc,splitAt在GHC中的实现方式如下: splitAt n xs = (take n xs, drop n xs) 那么,splitAt是否会加倍工作,或者是否有一些幕后优化 此外,take和drop生成一个递归过程。这是为什么。毕竟,它们是图书馆的功能,而美并不那么重要。为什么不实现它们来创建一个迭代过程 您正在查看的定义是前奏曲定义 引用那一页(我的重点) 本章给出了整个哈斯克尔前奏曲。它构成了序曲的规范。许多定义都是为了清晰而不是为了效率而编写的,并且不需要按照此处所示的方式实现规
splitAt n xs = (take n xs, drop n xs)
您正在查看的定义是前奏曲定义 引用那一页(我的重点) 本章给出了整个哈斯克尔前奏曲。它构成了序曲的规范。许多定义都是为了清晰而不是为了效率而编写的,并且不需要按照此处所示的方式实现规范 所以在GHC源中,当你看到
#ifdef USE_REPORT_PRELUDE
// Haskell report prelude definition here (inefficient)
#else
// Efficient definition here
#endif
如果您想查看通常使用的定义,您应该阅读
#else
分支,除非您特别要求Haskell报告定义。关于第二个问题,在处理列表时,递归过程通常是您想要的,因为它们是一种数据结构。考虑下面的代码:
head(取100[1..])
如果我们遵循代码,我们最终将得到以下表达式:
1:take(100-1)[2..]
。因为我们只对列表的开头感兴趣,所以对take
的递归调用永远不会被计算。但是,如果将take
作为一个迭代过程来实现,则需要迭代所有100个元素,即使只需要第一个元素。这不是GHC中定义的splitAt
。再看看。(2)“递归”是对解的归纳定义;使用另一个问题的解决方案来构建一个问题的解决方案的方法。不清楚“迭代过程”是什么意思,也不清楚为什么它是一个问题。我不相信split
的复杂定义比使用take
和drop
@augustss的天真定义好——至少在所有情况下都不好。我正在考虑写一篇关于这个的文章。@RomanCheplyaka,请写吧,我想这会很有启发性。