繁体   English   中英

使用Java代码中的Frege List

[英]Use Frege List from Java code

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

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

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解释TList正确?
  • TListIterator是否正确?
  • 我在哪里可以找到什么更多的信息TListDListDCons都在弗雷格编译器的源代码? 他们有记录吗?
  • 关于Frege最佳实践的更通用的问题:当您希望Java代码使用Frege值时,从Frege代码返回Java“标准”对象是否更好?或者直接使用Java中的Frege类更好吗? 我的观点是前者比后者更容易编写,但转换开销很小。 例如, TListIterator总是可以通过将避免TList到Java LinkedList从弗雷格。

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

除其他外,它解释了如何在Java代码中显示frege数据声明。

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

data List a = List | Cons a (List a)

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

以下是与上述内容对应的Java代码的概要:

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,那肯定是最好的。 如果这不起作用并且您需要一个列表,那么使用自定义迭代器的方法是可取的,恕我直言。 另一种方法是创建一个Java List,但这不是纯粹的,因为List必须在Frege中声明为mutable。 此外,通过有效地复制列表,您将浪费空间。

另一种可能性是返回一个数组。 例如,您可以在REPL中看到以下内容

foo a b c = arrayFromList [a,b,c] :: JArray Int

会得到如下签名:

final public static int[] foo(...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM