F# 中的变形

Catamorphism in F#

我正在阅读有关变形的维基百科文章,目前我能够在 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 就此而言)类型系统中 - 你运气不好。语言中缺少太多必需的机制——最关键的是更高种类的类型。

HKT 可以使用称为 defunctionalization. There is an F# library based on the concepts from this paper - Higher. In fact, it already implements fix, cata/ana/hylomorphisms and algebras 的技术在 F# 中编码,作为概念证明。不过,无论是在性能还是易用性方面,我都无法很好地衡量它的效果。

除此之外,您可以手动实现专门用于容器的折叠,而无需 HKT。现在有一个关于实现变形的经典系列博客文章 here。非常值得一读 - 除了折叠之外,它还深入介绍了连续传递风格的编程。