PragPub的实用递归方案

Jared Tobin is one of our consultants at fugue.co—he’s a programmer and researcher based out of Auckland, New Zealand. Jared’s article in this month’s issue of PragPub, The Pragmatic Bookshelf’s magazine affiliation, is a helpful read if you’re interested in functional programming and Haskell in particular. Check out “Practical Recursion Schemes” here.

贾里德·托宾(Jared Tobin)是fugue.co的顾问之一,他是一名来自新西兰奥克兰的程序员和研究员。 如果您对函数式编程特别是Haskell感兴趣,那么Jared在本月的PragPub杂志(实用书架的杂志隶属关系)上的文章对您很有帮助。 在此处查看“实用递归方案”。

Recursion schemes are simple, composable combinators that automate traversing nested data structures. They are a powerful abstraction that can be implemented in any language with first-class functions. Jared explores various schemes and their applications using Haskell, but the lessons here can be applied in Clojure or any true functional language.

递归方案是简单的,可组合的组合器,可自动遍历嵌套的数据结构。 它们是强大的抽象,可以用任何具有一流功能的语言来实现。 Jared使用Haskell探索了各种方案及其应用,但是这里的课程可以用Clojure或任何真正的函数式语言来应用。

The article details a number of recursion scheme examples. One of them is a particularly concise implementation of mergesort and, to wet your whistle for the kind of code you can write using recursion schemes, Jared elaborates on that example below.

本文详细介绍了许多递归方案示例。 其中之一是mergesort的一种特别简洁的实现,并且为了让您为使用递归方案可以编写的那种代码而烦恼,Jared在下面的示例中进行了详细说明。

按样式排序 (Sorting with Style)

Mergesort is a famous comparison-based sorting algorithm that starts by first recursively dividing a collection of orderable elements into smaller subcollections, and then finishes by recursively sorting and merging the smaller subcollections together to reconstruct the original (but now sorted) one.

Mergesort是一种著名的基于比较的排序算法,首先将可排序元素的集合递归地划分为较小的子集合,然后以递归的方式将较小的子集合归并并合并在一起以重建原始(但现在已排序)集合。

A clear implementation of mergesort should by definition be as faithful to that high-level description as possible. We can get pretty close to that using this whole recursion schemes business.

根据定义,对mergesort的清晰实现应尽可能忠实于该高级描述。 我们可以使用整个递归方案业务与之非常接近。

Start with a collection of orderable elements. We can subdivide the collection into a bunch of smaller collections by using a binary tree:

从可订购元素的集合开始。 我们可以使用二叉树将集合细分为一堆较小的集合:

data TreeF a r =
    EmptyF
  | LeafF a
  | NodeF r r
  deriving Functor
data TreeF a r =
    EmptyF
  | LeafF a
  | NodeF r r
  deriving Functor

The idea is that each node in the tree holds two subtrees, each of which contains half of the remaining elements. We can build a tree like this from a collection—say, a basic Haskell list. The following unfolder function defines what part of a tree to build for any corresponding part of a list:

这个想法是树中的每个节点都包含两个子树,每个子树包含剩余元素的一半。 我们可以从集合中构建像这样的树-例如基本的Haskell列表。 以下unfolder功能定义了列表的任何对应部分要构建的树的哪一部分:

On the other hand, we can collapse an existing tree back into a list. The following folder function defines how to collapse any given part of a tree into the corresponding part of a list:

另一方面,我们可以将现有树折叠回到列表中。 以下folder函数定义如何将树的任何给定部分折叠到列表的相应部分中:

folder EmptyF      = []
folder (LeafF x)   = [x]
folder (NodeF l r) = merge l r
folder EmptyF      = []
folder (LeafF x)   = [x]
folder (NodeF l r) = merge l r

Now to sort a list we can just glue these instructions together using what’s called a hylomorphism.

现在要对列表进行排序,我们可以使用所谓的同形将这些指令粘合在一起。

And it works just like you’d expect:

它的工作原理与您期望的一样:

> mergesort [1,10,3,4,5]
[1,3,4,5,10]
> mergesort "aloha"
"aahlo"
> mergesort [True, False, False, True, False]
[False, False, False, True, True]
> mergesort [ 1 , 10 , 3 , 4 , 5 ]
[ 1 , 3 , 4 , 5 , 10 ]
> mergesort "aloha"
"aahlo"
> mergesort [T rue , F alse , F alse , T rue , F alse ]
[F alse , F alse , F alse , T rue , T rue ]

Pretty concise! The code is eminently clean and faithful to the high-level algorithm description: first, recursively divide a collection into smaller subcollections—via a binary tree and unfolder—and then recursively sort and merge the subcollections to reconstruct the (now sorted) original one—via folder.

简明扼要! 该代码非常干净,并且忠实于高级算法描述:首先,通过二叉树和unfolder将一个集合递归地划分为较小的子集合,然后递归地对子集合进行排序和合并,以重建(现在已排序的)原始集合。通过folder

Share

分享

Twitter

推特

Reddit

Reddit

Google+

Google+

Facebook

脸书

翻译自: https://www.pybloggers.com/2015/12/practical-recursion-schemes-at-pragpub/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值