簡體   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