[英]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
是否正確? TList
, DList
和DCons
都在弗雷格編譯器的源代碼? 他們有記錄嗎? 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中的重復名稱:
Foo
在Java中得到名稱TFoo
。 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.