我正在阅读有关变态现象的维基百科文章,目前,除了这一部分之外,我能够重现F#中的Haskell示例:
type Algebra f a = f a -> a -- the generic f-algebras
newtype Fix f = Iso { invIso :: f (Fix f) } -- gives us the initial algebra for the functor f
cata :: Functor f => Algebra f a -> (Fix f -> a) -- catamorphism from Fix f to a
cata alg = alg . fmap (cata alg) . invIso -- note that invIso and alg map in opposite directions
在F#中可以这样做吗?
最佳答案
如果您想在任意容器类型(a'la recursion schemes)上直接在F#(或CLR)类型系统中表达真正的通用折叠,那么您就不走运了。语言中缺少太多所需的机器-最关键的是更高种类的机器。
但是,可以使用称为defunctionalization的技术在F#中对HKT进行编码。有一个基于本文概念的F#库-更高。实际上,它已经实现了fix, cata/ana/hylomorphisms和algebras作为概念证明。从性能和易用性两方面,我都无法很好地衡量其效果。
除此之外,您还可以手工实现针对您的集装箱的折叠,从而无需使用HKT。到目前为止,在经典博客系列中,有一系列关于实现变态here的文章。值得一读-除折叠之外,它还以连续传递样式深入编程。