当前位置: 首页 > 知识库问答 >
问题:

如何在Java中实现函子的不动点

安泰平
2023-03-14

我最近发现了如何在Java中以某种迂回的方式模拟更高级的类型

interface H<F, T> { }

这里,H编码一种更高级的类型,该类型采用类型参数F,其本身采用参数T

现在这让我想知道,我们可以用它来实现一些更高级的构造吗?例如,Haskell中Fix之类的函子的不动点及其对应的反态?

共有1个答案

雷献
2023-03-14

事实上,这可以通过仔细翻译相应的Haskell副本来实现。尽管这会引入大量线路噪声,但其实现与最初的非常接近:

// Encoding of higher kinded type F of T
public interface H<F, T> { }

public interface Functor<F, T> {
    <R> H<F, R> map(Function<T, R> f);
}

// newtype Fix f = Fix {unfix::f (Fix f)}
public static record Fix<F extends H<F, T> & Functor<F, T>, T>(F f) {
    public Functor<F, Fix<F, T>> unfix() {
        return (Functor<F, Fix<F, T>>) f;
    }
}

// type Algebra f a = f a -> a
public interface Algebra<F, T> extends Function<H<F, T>, T> {}

 // cata :: Functor f => Algebra f a -> Fix f -> a
 // cata alg = alg . fmap (cata alg) . unfix
public static <F extends H<F, T> & Functor<F, T>, T> Function<Fix<F, T>, T> cata(Algebra<F, T> alg) {
    return fix -> alg.apply(fix.unfix().map(cata(alg)));
}

令人惊讶的是,这是可行的,可以用来实现表达式代数的解释器

// evalExprF :: Algebra ExprF Int
// evalExprF (Const n) = n
// evalExprF (Add m n) = m + n
// evalExprF (Mul m n) = m * n
public static class ExprAlg implements Algebra<Expr, Integer> {
    @Override
    public Integer apply(H<Expr, Integer> hExpr) {
        return Expr.expr(hExpr).match(
            conzt -> conzt.n,
            add   -> add.t1 + add.t2,
            mul   -> mul.t1 * mul.t2);
    }
}

我的GitHub存储库中的完整工作示例。

 类似资料:
  • 本文向大家介绍如何在 Java 中实现不可变类,包括了如何在 Java 中实现不可变类的使用技巧和注意事项,需要的朋友参考一下 前言 面向对象的编程通过封装可变动的部分来构造能够让人读懂的代码,函数式编程则是通过最大程度地减少 可变动的部分来构造出可让人读懂的代码。 — Michael Feathers,Working with Legacy Code 一文的作者 在这一部分中,我讨论的是函数式编

  • 本文向大家介绍vue.js动画中的js钩子函数的实现,包括了vue.js动画中的js钩子函数的实现的使用技巧和注意事项,需要的朋友参考一下 在transition中还可以通过设置javascript钩子函数,实现自定义动画效果。 以实现击球效果为例: 击球 代码解析: 完整代码 最终效果: 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。

  • 问题内容: 我在Swift操场上有以下示例,试图在Swift中实现一个副本构造函数: 问题在于这实际上并不能以当前形式进行编译。在子类中的 方法上,报告此错误: 如果它不是 构造函数 ,就好比是常规的,那么这个问题 就很有意义 了,您可以传递超类中期望的类型,但在子类中已重写该类型以限制更多: __ 但是事实是它是 构造函数 ,这使我相信我应该能够重写它并提供不同的方法签名,因为在编译时绝对知道对

  • 我一直在努力尝试让Bouncy Castle Scrypt进入我的web应用程序进行密码加密。我对Java编程和安全性相当陌生。 我试着查看了Bouncy Castle的Scrypt类文档。然而,我真的很难弄清楚它是如何工作的。它似乎并没有真正给出如何创建类或诸如此类的信息。 我在Stack Exchange和Google上搜索了一下,看看是否有什么地方可以给出一个很好的示例,说明我应该做什么来创

  • 我的Kotlin项目需要一个Java注释。 不幸的是,这似乎很困难。我在这里找到了这种讨论: https://discuss.kotlinlang.org/t/intdef-and-stringdef-not-being-checked-at-compile-time/7029/3 我明白这可能是一个Lint问题。不执行编译时检查。两人都没有提出任何建议。我可以添加任何字符串作为参数。 我最终用我

  • 从Udacity的深度学习类来看,y_i的软最大值只是指数除以整个Y向量的指数之和: 其中< code>S(y_i)是< code>y_i的softmax函数,而< code>e是指数,而< code>j是输入向量y中的列数 我尝试了以下方法: 返回: 但建议的解决方案是: 它产生与第一个实现相同的输出,即使第一个实现显式地取每列和max的差值,然后除以总和。 有人能用数学说明为什么吗?一个正确,