自定义euc函数是否属于recursion-schemes中的某类态射?
解答
你的euc算子不属于apo态射的特化,二者的设计目标存在本质差异,对应递归态射的说明如下:
核心差异
apo态射的定位是构造递归数据结构,从它的类型签名可以明确看出来:
apo :: Functor f => (t -> f (Either (Fix f) t)) -> t -> Fix f
它的返回值是Fix f,也就是递归类型的不动点结构,生成过程中可以通过Left分支插入现成的递归子结构来提前终止某一分支的展开,和你的需求场景完全不符。
你实现的euc是尾递归迭代的通用抽象,目标是通过反复调用步进函数直接产出最终值,不需要构造任何中间递归结构。
对应标准递归态射
你的euc本质是recursion-schemes中**hylomorphism(常缩写为hylo,变质态射)**在函子为Either t时的特化版本。
hylomorphism的作用是将一次共递归展开(ana)和一次递归折叠(cata)结合,不需要生成中间的递归结构,完全匹配你的尾递归迭代场景,二者的等价实现如下:
import Data.Functor.Foldable euc :: (a -> Either t a) -> a -> t euc psi = hylo (either id id) psi
其中either id id就是折叠函数,负责把展开到最后的Left t直接作为结果返回。
欧几里得算法的递归方案实现
沿用你原本的步进逻辑,用标准hylo实现的欧几里得算法如下,和你原本的实现语义完全等价:
euclid :: Integral a => a -> a -> a euclid x y = hylo (either id id) psi (x, y) where psi (x, y) = let m = x `mod` y in if m == 0 then Left y else Right (y, m)
如果你非要用apo实现也可以,但是需要额外定义辅助递归结构来承载迭代过程,属于为了套标准态射而做的冗余实现,没有实际使用价值。
内容的提问来源于stack exchange,提问作者いとうかつとし
相关产品推荐
相关产品推荐

