我想了解Frege是如何工作的,以及如何从Java中使用它。当我下载了Frege编译器代码时,我发现很难理解Frege代码中的Frege列表是什么。
在进行一些测试时,我看到一个Frege是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的解释正确吗?TListIterator是对的吗?TList、DList和DCons在Frege编译器源代码中的信息?有记录吗?TListIterator转换为TList的LinkedList来避免使用Frege。发布于 2014-05-14 00:35:31
首先,从Java调用Frege的最终指南是这个wiki page。
它解释了frege数据声明是如何在Java代码中出现的。
列表的唯一特别之处在于,在任何地方都没有明确的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中的重复名称:
Foo在Java中获得名称TFoo。Bar获得名称DBarDBar的方法是_Bar。(请注意,没有显式字段对构造函数进行编码,这样我们就可以使用JVM对象标头来进行编码)当然,这个名字乍一看有点神秘。但它也不适合普通用户。事实上,我不认为从Java调用Frege对任何人来说都是有趣的。但现在我的想法不同了,我们正在设计一种方法,使在Frege中实现Java接口成为可能(看起来,这也将为您的目的服务)。
关于你的最后一个问题,我认为这要看情况而定。如果您只返回int、double或string,这肯定是最好的。如果这不起作用,而且您需要一个列表,那么您使用自定义Iterator的方法会更好,IMHO。另一种方法是创建一个Java列表,但这并不是纯的,因为列表必须在Frege中声明为可变的。此外,通过有效地复制列表,您将浪费空间。
另一种可能是返回数组。例如,正如您在REPL中所看到的,
foo a b c = arrayFromList [a,b,c] :: JArray Int会得到这样的签名:
final public static int[] foo(...https://stackoverflow.com/questions/23642567
复制相似问题