首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Java代码中的Frege列表

使用Java代码中的Frege列表
EN

Stack Overflow用户
提问于 2014-05-13 22:19:56
回答 1查看 459关注 0票数 5

我想了解Frege是如何工作的,以及如何从Java中使用它。当我下载了Frege编译器代码时,我发现很难理解Frege代码中的Frege列表是什么。

在进行一些测试时,我看到一个Frege是TList类的一个实例,它使用一个名为_Cons()的特殊方法返回DCons对象。正如预期的那样,DCons是一对,其中该对的第一个元素对应于列表的头,而第二个元素是尾,因此是另一个TList。当对空列表调用_Cons()时,返回值为null。因此,要在Frege TList上实现Java迭代器,可以编写:

代码语言:javascript
复制
public class TListIterator implements Iterator<Object> {
    DCons elem;
    public TListIterator(TList list) {
      this.elem = list._Cons();
    }

    @Override
    public boolean hasNext() {
      return this.elem != null;
    }

    @Override
    public Object next() {
      final Object head = Delayed.<Object>forced( this.elem.mem1 );
      this.elem = this.elem.mem2.<TList>forced()._Cons();
      return head;
    }

    @Override
    public void remove() {
      throw new RuntimeException( "Remove is not implemented" );
    }
}

我的问题是:

  • 我对TList的解释正确吗?
  • TListIterator是对的吗?
  • 在哪里可以找到更多关于TListDListDCons在Frege编译器源代码中的信息?有记录吗?
  • 关于Frege中最佳实践的一个更普遍的问题:当您希望Java代码使用Frege值时,从Frege代码返回Java“标准”对象更好还是直接从Java中使用Frege类更好?我的观点是前者比后者更容易编写,但是有一些转换开销。例如,可以通过将TListIterator转换为TListLinkedList来避免使用Frege。
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-05-14 00:35:31

首先,从Java调用Frege的最终指南是这个wiki page

它解释了frege数据声明是如何在Java代码中出现的。

列表的唯一特别之处在于,在任何地方都没有明确的Frege声明,但我们可以假设它看起来是:

代码语言:javascript
复制
data List a = List | Cons a (List a)

注意,等号后面的标识符List是空列表的构造函数,通常称为Nil。之所以将其命名为List (与类型相同),是因为将frege名称损坏为有效的java名称的例程将[]转换为List。在Frege源代码中,我们使用[]作为类型名和构造函数名。

下面是与上述内容相对应的Java代码的大纲:

代码语言:javascript
复制
public interface TList extends frege.runtime.Value, frege.runtime.Lazy {
  public TList.DCons _Cons() ;
  public TList.DList _List() ;
  final public static class DCons extends frege.runtime.Algebraic implements TList {
    private DCons(final java.lang.Object arg$1, final frege.runtime.Lazy arg$2) {
      mem1 = arg$1; mem2 = arg$2;
    }
    final public static TList mk(final java.lang.Object arg$1, final frege.runtime.Lazy arg$2) {
      return new DCons(arg$1, arg$2);
    }
    final public DCons _Cons() { return this; }
    final public TList.DList _List() { return null; }
    final public java.lang.Object mem1 ;
    final public frege.runtime.Lazy mem2 ;
  }
  final public static class DList extends frege.runtime.Algebraic implements TList {
    private DList() {}
    final public static TList mk() { return it; }
    final public static DList it = new DList();
    final public DList _List() { return this;}
    final public TList.DCons _Cons() { return null; }
  }
}

正如您所看到的,整个类型是一个接口TList。对于列表,您唯一能做的就是检查变体,为此,我们有方法_List()和_Cons()。正如您正确观察到的,_Cons()返回空列表的null,以及非空列表的TLIst.DCons实例。从那里可以提取头部(mem1)和尾部(mem2)。

据我所见,您的列表迭代器应该可以正常工作。

观察简单的编码以避免Java中的重复名称:

  • Frege类型的Foo在Java中获得名称TFoo
  • Frege数据构造函数Bar获得名称DBar
  • 检查我们是否有DBar的方法是_Bar。(请注意,没有显式字段对构造函数进行编码,这样我们就可以使用JVM对象标头来进行编码)

当然,这个名字乍一看有点神秘。但它也不适合普通用户。事实上,我不认为从Java调用Frege对任何人来说都是有趣的。但现在我的想法不同了,我们正在设计一种方法,使在Frege中实现Java接口成为可能(看起来,这也将为您的目的服务)。

关于你的最后一个问题,我认为这要看情况而定。如果您只返回int、double或string,这肯定是最好的。如果这不起作用,而且您需要一个列表,那么您使用自定义Iterator的方法会更好,IMHO。另一种方法是创建一个Java列表,但这并不是纯的,因为列表必须在Frege中声明为可变的。此外,通过有效地复制列表,您将浪费空间。

另一种可能是返回数组。例如,正如您在REPL中所看到的,

代码语言:javascript
复制
foo a b c = arrayFromList [a,b,c] :: JArray Int

会得到这样的签名:

代码语言:javascript
复制
final public static int[] foo(...
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23642567

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档